Skip to main content

diesel/sqlite/types/
mod.rs

1mod date_and_time;
2mod enum_;
3#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
4mod json;
5mod numeric;
6
7use super::Sqlite;
8use super::connection::SqliteValue;
9use crate::deserialize::{self, FromSql, FromSqlRef, Queryable};
10use crate::expression::AsExpression;
11use crate::query_builder::QueryId;
12use crate::serialize::{self, IsNull, Output, ToSql};
13use crate::sql_types;
14use crate::sql_types::SqlType;
15
16/// The returned pointer is *only* valid for the lifetime to the argument of
17/// `from_sql`. This impl is intended for uses where you want to write a new
18/// impl in terms of `String`, but don't want to allocate. We have to return a
19/// raw pointer instead of a reference with a lifetime due to the structure of
20/// `FromSql`
21#[cfg(feature = "__sqlite-shared")]
22impl FromSql<sql_types::VarChar, Sqlite> for *const str {
23    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
24        let text = value.read_text();
25        Ok(text as *const _)
26    }
27}
28
29#[cfg(feature = "__sqlite-shared")]
30impl<'a> FromSqlRef<'a, sql_types::VarChar, Sqlite> for &'a str {
31    fn from_sql(value: &'a mut SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
32        Ok(value.as_utf8_str()?)
33    }
34}
35
36#[cfg(feature = "__sqlite-shared")]
37impl Queryable<sql_types::VarChar, Sqlite> for *const str {
38    type Row = Self;
39
40    fn build(row: Self::Row) -> deserialize::Result<Self> {
41        Ok(row)
42    }
43}
44
45/// The returned pointer is *only* valid for the lifetime to the argument of
46/// `from_sql`. This impl is intended for uses where you want to write a new
47/// impl in terms of `Vec<u8>`, but don't want to allocate. We have to return a
48/// raw pointer instead of a reference with a lifetime due to the structure of
49/// `FromSql`
50#[cfg(feature = "__sqlite-shared")]
51impl FromSql<sql_types::Binary, Sqlite> for *const [u8] {
52    fn from_sql(mut bytes: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
53        let bytes = bytes.read_blob();
54        Ok(bytes as *const _)
55    }
56}
57
58#[cfg(feature = "__sqlite-shared")]
59impl<'a> FromSqlRef<'a, sql_types::Binary, Sqlite> for &'a [u8] {
60    fn from_sql(value: &'a mut SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
61        Ok(value.read_blob())
62    }
63}
64
65#[cfg(feature = "__sqlite-shared")]
66impl Queryable<sql_types::Binary, Sqlite> for *const [u8] {
67    type Row = Self;
68
69    fn build(row: Self::Row) -> deserialize::Result<Self> {
70        Ok(row)
71    }
72}
73
74#[cfg(feature = "__sqlite-shared")]
75#[allow(clippy::cast_possible_truncation)] // we want to truncate here
76impl FromSql<sql_types::SmallInt, Sqlite> for i16 {
77    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
78        Ok(value.read_integer() as i16)
79    }
80}
81
82#[cfg(feature = "__sqlite-shared")]
83impl FromSql<sql_types::Integer, Sqlite> for i32 {
84    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
85        Ok(value.read_integer())
86    }
87}
88
89#[cfg(feature = "__sqlite-shared")]
90impl FromSql<sql_types::Bool, Sqlite> for bool {
91    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
92        Ok(value.read_integer() != 0)
93    }
94}
95
96#[cfg(feature = "__sqlite-shared")]
97impl FromSql<sql_types::BigInt, Sqlite> for i64 {
98    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
99        Ok(value.read_long())
100    }
101}
102
103#[cfg(feature = "__sqlite-shared")]
104#[allow(clippy::cast_possible_truncation)] // we want to truncate here
105impl FromSql<sql_types::Float, Sqlite> for f32 {
106    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
107        Ok(value.read_double() as f32)
108    }
109}
110
111#[cfg(feature = "__sqlite-shared")]
112impl FromSql<sql_types::Double, Sqlite> for f64 {
113    fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
114        Ok(value.read_double())
115    }
116}
117
118#[cfg(feature = "__sqlite-shared")]
119impl ToSql<sql_types::Bool, Sqlite> for bool {
120    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
121        let int_value = if *self { &1 } else { &0 };
122        <i32 as ToSql<sql_types::Integer, Sqlite>>::to_sql(int_value, out)
123    }
124}
125
126#[cfg(feature = "__sqlite-shared")]
127impl ToSql<sql_types::Text, Sqlite> for str {
128    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
129        out.set_value(self);
130        Ok(IsNull::No)
131    }
132}
133
134#[cfg(feature = "__sqlite-shared")]
135impl ToSql<sql_types::Binary, Sqlite> for [u8] {
136    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
137        out.set_value(self);
138        Ok(IsNull::No)
139    }
140}
141
142#[cfg(feature = "__sqlite-shared")]
143impl ToSql<sql_types::SmallInt, Sqlite> for i16 {
144    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
145        out.set_value(*self as i32);
146        Ok(IsNull::No)
147    }
148}
149
150#[cfg(feature = "__sqlite-shared")]
151impl ToSql<sql_types::Integer, Sqlite> for i32 {
152    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
153        out.set_value(*self);
154        Ok(IsNull::No)
155    }
156}
157
158#[cfg(feature = "__sqlite-shared")]
159impl ToSql<sql_types::BigInt, Sqlite> for i64 {
160    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
161        out.set_value(*self);
162        Ok(IsNull::No)
163    }
164}
165
166#[cfg(feature = "__sqlite-shared")]
167impl ToSql<sql_types::Float, Sqlite> for f32 {
168    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
169        out.set_value(*self as f64);
170        Ok(IsNull::No)
171    }
172}
173
174#[cfg(feature = "__sqlite-shared")]
175impl ToSql<sql_types::Double, Sqlite> for f64 {
176    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
177        out.set_value(*self);
178        Ok(IsNull::No)
179    }
180}
181
182/// The SQLite timestamp with time zone type
183///
184/// ### [`ToSql`] impls
185///
186/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
187/// - [`chrono::DateTime`] with `feature = "chrono"`
188/// - [`time::PrimitiveDateTime`] with `feature = "time"`
189/// - [`time::OffsetDateTime`] with `feature = "time"`
190///
191/// ### [`FromSql`] impls
192///
193/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
194/// - [`chrono::DateTime`] with `feature = "chrono"`
195/// - [`time::PrimitiveDateTime`] with `feature = "time"`
196/// - [`time::OffsetDateTime`] with `feature = "time"`
197///
198/// [`ToSql`]: crate::serialize::ToSql
199/// [`FromSql`]: crate::deserialize::FromSql
200#[cfg_attr(
201    feature = "chrono",
202    doc = " [`chrono::NaiveDateTime`]: chrono::naive::NaiveDateTime"
203)]
204#[cfg_attr(
205    not(feature = "chrono"),
206    doc = " [`chrono::NaiveDateTime`]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDateTime.html"
207)]
208#[cfg_attr(feature = "chrono", doc = " [`chrono::DateTime`]: chrono::DateTime")]
209#[cfg_attr(
210    not(feature = "chrono"),
211    doc = " [`chrono::DateTime`]: https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html"
212)]
213#[cfg_attr(
214    feature = "time",
215    doc = " [`time::PrimitiveDateTime`]: time::PrimitiveDateTime"
216)]
217#[cfg_attr(
218    not(feature = "time"),
219    doc = " [`time::PrimitiveDateTime`]: https://docs.rs/time/0.3.9/time/struct.PrimitiveDateTime.html"
220)]
221#[cfg_attr(
222    feature = "time",
223    doc = " [`time::OffsetDateTime`]: time::OffsetDateTime"
224)]
225#[cfg_attr(
226    not(feature = "time"),
227    doc = " [`time::OffsetDateTime`]: https://docs.rs/time/0.3.9/time/struct.OffsetDateTime.html"
228)]
229#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Timestamptz {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Timestamptz")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Timestamptz {
    #[inline]
    fn clone(&self) -> Timestamptz { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Timestamptz { }Copy, #[automatically_derived]
impl ::core::default::Default for Timestamptz {
    #[inline]
    fn default() -> Timestamptz { Timestamptz {} }
}Default, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Timestamptz {
            type QueryId = Timestamptz<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl diesel::sql_types::SqlType for Timestamptz {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl diesel::sql_types::SingleValue for Timestamptz {}
        impl diesel::sql_types::HasSqlType<Timestamptz> for
            diesel::sqlite::Sqlite {
            fn metadata(_: &mut ()) -> diesel::sqlite::SqliteType {
                diesel::sqlite::SqliteType::Text
            }
        }
    };SqlType)]
230#[diesel(sqlite_type(name = "Text"))]
231#[cfg(feature = "__sqlite-shared")]
232pub struct Timestamptz;
233
234/// The SQL type for JSON validation flags
235///
236/// This type is backed by an Integer in SQLite.
237///
238/// ### [`ToSql`] impls
239///
240/// - [`JsonValidFlag`]
241///
242/// [`ToSql`]: crate::serialize::ToSql
243#[derive(#[automatically_derived]
impl ::core::fmt::Debug for JsonValidFlags {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "JsonValidFlags")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for JsonValidFlags {
    #[inline]
    fn clone(&self) -> JsonValidFlags { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for JsonValidFlags { }Copy, #[automatically_derived]
impl ::core::default::Default for JsonValidFlags {
    #[inline]
    fn default() -> JsonValidFlags { JsonValidFlags {} }
}Default, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for JsonValidFlags {
            type QueryId = JsonValidFlags<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl diesel::sql_types::SqlType for JsonValidFlags {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl diesel::sql_types::SingleValue for JsonValidFlags {}
        impl diesel::sql_types::HasSqlType<JsonValidFlags> for
            diesel::sqlite::Sqlite {
            fn metadata(_: &mut ()) -> diesel::sqlite::SqliteType {
                diesel::sqlite::SqliteType::Integer
            }
        }
    };SqlType)]
244#[diesel(sqlite_type(name = "Integer"))]
245#[cfg(feature = "__sqlite-shared")]
246pub struct JsonValidFlags;
247
248/// Flags for the `json_valid` function
249///
250/// These flags define what is meant by "well-formed" JSON when validating.
251///
252/// The following bits are currently defined:
253/// - `0x01` → The input is text that strictly complies with canonical RFC-8259 JSON, without any extensions.
254/// - `0x02` → The input is text that is JSON with JSON5 extensions.
255/// - `0x04` → The input is a BLOB that superficially appears to be JSONB.
256/// - `0x08` → The input is a BLOB that strictly conforms to the internal JSONB format.
257///
258/// By combining bits, the following useful values can be derived:
259/// - `Rfc8259Json` (1) → X is RFC-8259 JSON text
260/// - `Json5` (2) → X is JSON5 text
261/// - `JsonbLike` (4) → X is probably JSONB
262/// - `Rfc8259JsonOrJsonb` (5) → X is RFC-8259 JSON text or JSONB
263/// - `Json5OrJsonb` (6) → X is JSON5 text or JSONB (recommended for most use cases)
264/// - `JsonbStrict` (8) → X is strictly conforming JSONB
265/// - `Rfc8259JsonOrJsonbStrict` (9) → X is RFC-8259 or strictly conforming JSONB
266/// - `Json5OrJsonbStrict` (10) → X is JSON5 or strictly conforming JSONB
267#[derive(#[automatically_derived]
impl ::core::fmt::Debug for JsonValidFlag {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                JsonValidFlag::Rfc8259Json => "Rfc8259Json",
                JsonValidFlag::Json5 => "Json5",
                JsonValidFlag::JsonbLike => "JsonbLike",
                JsonValidFlag::Rfc8259JsonOrJsonb => "Rfc8259JsonOrJsonb",
                JsonValidFlag::Json5OrJsonb => "Json5OrJsonb",
                JsonValidFlag::JsonbStrict => "JsonbStrict",
                JsonValidFlag::Rfc8259JsonOrJsonbStrict =>
                    "Rfc8259JsonOrJsonbStrict",
                JsonValidFlag::Json5OrJsonbStrict => "Json5OrJsonbStrict",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for JsonValidFlag {
    #[inline]
    fn clone(&self) -> JsonValidFlag { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for JsonValidFlag { }Copy, const _: () =
    {
        use diesel;
        impl<'__expr> diesel::expression::AsExpression<JsonValidFlags> for
            &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        #[diagnostic::do_not_recommend]
        impl<'__expr>
            diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        #[diagnostic::do_not_recommend]
        impl<'__expr, '__expr2>
            diesel::expression::AsExpression<JsonValidFlags> for
            &'__expr2 &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        #[diagnostic::do_not_recommend]
        impl<'__expr, '__expr2>
            diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for &'__expr2 &'__expr JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl<__DB>
            diesel::serialize::ToSql<diesel::sql_types::Nullable<JsonValidFlags>,
            __DB> for JsonValidFlag where __DB: diesel::backend::Backend,
            Self: diesel::serialize::ToSql<JsonValidFlags, __DB> {
            fn to_sql<'__b>(&'__b self,
                out: &mut diesel::serialize::Output<'__b, '_, __DB>)
                -> diesel::serialize::Result {
                diesel::serialize::ToSql::<JsonValidFlags,
                        __DB>::to_sql(self, out)
            }
        }
        impl diesel::expression::AsExpression<JsonValidFlags> for
            JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<JsonValidFlags,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<JsonValidFlags>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
        impl diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>
            for JsonValidFlag {
            type Expression =
                diesel::internal::derives::as_expression::Bound<diesel::sql_types::Nullable<JsonValidFlags>,
                Self>;
            fn as_expression(self)
                ->
                    <Self as
                    diesel::expression::AsExpression<diesel::sql_types::Nullable<JsonValidFlags>>>::Expression {
                diesel::internal::derives::as_expression::Bound::new(self)
            }
        }
    };AsExpression)]
268#[diesel(sql_type = JsonValidFlags)]
269#[cfg(feature = "__sqlite-shared")]
270#[non_exhaustive]
271pub enum JsonValidFlag {
272    /// X is RFC-8259 JSON text (flag = 1)
273    Rfc8259Json = 1,
274    /// X is JSON5 text (flag = 2)
275    Json5 = 2,
276    /// X is probably JSONB (flag = 4)
277    JsonbLike = 4,
278    /// X is RFC-8259 JSON text or JSONB (flag = 5)
279    Rfc8259JsonOrJsonb = 5,
280    /// X is JSON5 text or JSONB (flag = 6, recommended for most use cases)
281    Json5OrJsonb = 6,
282    /// X is strictly conforming JSONB (flag = 8)
283    JsonbStrict = 8,
284    /// X is RFC-8259 or strictly conforming JSONB (flag = 9)
285    Rfc8259JsonOrJsonbStrict = 9,
286    /// X is JSON5 or strictly conforming JSONB (flag = 10)
287    Json5OrJsonbStrict = 10,
288}
289
290#[cfg(feature = "__sqlite-shared")]
291impl ToSql<JsonValidFlags, Sqlite> for JsonValidFlag {
292    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
293        out.set_value(*self as i32);
294        Ok(IsNull::No)
295    }
296}