Skip to main content

diesel/mysql_like/types/
mod.rs

1//! MySQL and Mariadb shared types
2
3pub(super) mod date_and_time;
4mod enum_;
5#[cfg(feature = "serde_json")]
6mod json;
7mod numeric;
8mod primitives;
9
10use crate::deserialize::{self, FromSql};
11use crate::mysql_like::MysqlLikeBackend;
12use crate::mysql_like::{MysqlType, MysqlValue};
13use crate::query_builder::QueryId;
14use crate::serialize::{self, IsNull, Output, ToSql};
15use crate::sql_types::ops::*;
16use crate::sql_types::*;
17use crate::sql_types::{self};
18use byteorder::{NativeEndian, WriteBytesExt};
19
20impl<DB: MysqlLikeBackend> ToSql<TinyInt, DB> for i8 {
21    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
22        out.write_i8(*self).map(|_| IsNull::No).map_err(Into::into)
23    }
24}
25
26impl<DB: MysqlLikeBackend> FromSql<TinyInt, DB> for i8 {
27    fn from_sql(value: DB::RawValue<'_>) -> deserialize::Result<Self> {
28        let bytes = value.as_bytes();
29        Ok(i8::from_be_bytes([bytes[0]]))
30    }
31}
32
33/// Represents the MySQL unsigned type.
34#[derive(#[automatically_derived]
impl<ST: ::core::fmt::Debug + 'static> ::core::fmt::Debug for Unsigned<ST> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unsigned",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl<ST: ::core::clone::Clone + 'static> ::core::clone::Clone for Unsigned<ST>
    {
    #[inline]
    fn clone(&self) -> Unsigned<ST> {
        Unsigned(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl<ST: ::core::marker::Copy + 'static> ::core::marker::Copy for Unsigned<ST>
    {
}Copy, #[automatically_derived]
impl<ST: ::core::default::Default + 'static> ::core::default::Default for
    Unsigned<ST> {
    #[inline]
    fn default() -> Unsigned<ST> {
        Unsigned(::core::default::Default::default())
    }
}Default, const _: () =
    {
        use diesel;
        impl<ST: 'static> diesel::sql_types::SqlType for Unsigned<ST> {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl<ST: 'static> diesel::sql_types::SingleValue for Unsigned<ST> {}
    };SqlType, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl<ST: 'static + diesel::query_builder::QueryId>
            diesel::query_builder::QueryId for Unsigned<ST> {
            type QueryId =
                Unsigned<<ST as diesel::query_builder::QueryId>::QueryId>;
            const HAS_STATIC_QUERY_ID: bool =
                <ST as diesel::query_builder::QueryId>::HAS_STATIC_QUERY_ID &&
                    true;
            const IS_WINDOW_FUNCTION: bool =
                <ST as diesel::query_builder::QueryId>::IS_WINDOW_FUNCTION ||
                    false;
        }
    };QueryId)]
35pub struct Unsigned<ST: 'static>(ST);
36
37impl<T> Add for Unsigned<T>
38where
39    T: Add,
40{
41    type Rhs = Unsigned<T::Rhs>;
42    type Output = Unsigned<T::Output>;
43}
44
45impl<T> Sub for Unsigned<T>
46where
47    T: Sub,
48{
49    type Rhs = Unsigned<T::Rhs>;
50    type Output = Unsigned<T::Output>;
51}
52
53impl<T> Mul for Unsigned<T>
54where
55    T: Mul,
56{
57    type Rhs = Unsigned<T::Rhs>;
58    type Output = Unsigned<T::Output>;
59}
60
61impl<T> Div for Unsigned<T>
62where
63    T: Div,
64{
65    type Rhs = Unsigned<T::Rhs>;
66    type Output = Unsigned<T::Output>;
67}
68
69impl<DB: MysqlLikeBackend> ToSql<Unsigned<TinyInt>, DB> for u8 {
70    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
71        out.write_u8(*self)?;
72        Ok(IsNull::No)
73    }
74}
75
76impl<DB: MysqlLikeBackend> FromSql<Unsigned<TinyInt>, DB> for u8 {
77    #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] // that's what we want
78    fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
79        let signed: i8 = FromSql::<TinyInt, DB>::from_sql(bytes)?;
80        Ok(signed as u8)
81    }
82}
83
84impl<DB: MysqlLikeBackend> ToSql<Unsigned<SmallInt>, DB> for u16 {
85    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
86        out.write_u16::<NativeEndian>(*self)?;
87        Ok(IsNull::No)
88    }
89}
90
91impl<DB: MysqlLikeBackend> FromSql<Unsigned<SmallInt>, DB> for u16
92where
93    i32: deserialize::FromSql<sql_types::Integer, DB>,
94{
95    #[allow(
96        clippy::cast_possible_wrap,
97        clippy::cast_sign_loss,
98        clippy::cast_possible_truncation
99    )] // that's what we want
100    fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
101        let signed: i32 = FromSql::<Integer, DB>::from_sql(bytes)?;
102        Ok(signed as u16)
103    }
104}
105
106impl<DB: MysqlLikeBackend> ToSql<Unsigned<Integer>, DB> for u32 {
107    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
108        out.write_u32::<NativeEndian>(*self)?;
109        Ok(IsNull::No)
110    }
111}
112
113impl<DB: MysqlLikeBackend> FromSql<Unsigned<Integer>, DB> for u32
114where
115    i64: deserialize::FromSql<sql_types::BigInt, DB>,
116{
117    #[allow(
118        clippy::cast_possible_wrap,
119        clippy::cast_sign_loss,
120        clippy::cast_possible_truncation
121    )] // that's what we want
122    fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
123        let signed: i64 = FromSql::<BigInt, DB>::from_sql(bytes)?;
124        Ok(signed as u32)
125    }
126}
127
128impl<DB: MysqlLikeBackend> ToSql<Unsigned<BigInt>, DB> for u64 {
129    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
130        out.write_u64::<NativeEndian>(*self)?;
131        Ok(IsNull::No)
132    }
133}
134
135impl<DB: MysqlLikeBackend> FromSql<Unsigned<BigInt>, DB> for u64
136where
137    i64: deserialize::FromSql<sql_types::BigInt, DB>,
138{
139    #[allow(
140        clippy::cast_possible_wrap,
141        clippy::cast_sign_loss,
142        clippy::cast_possible_truncation
143    )] // that's what we want
144    fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
145        let signed: i64 = FromSql::<BigInt, DB>::from_sql(bytes)?;
146        Ok(signed as u64)
147    }
148}
149
150impl<DB: MysqlLikeBackend> ToSql<Bool, DB> for bool {
151    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
152        let int_value = i32::from(*self);
153        <i32 as ToSql<Integer, DB>>::to_sql(&int_value, &mut out.reborrow())
154    }
155}
156
157impl<DB: MysqlLikeBackend> FromSql<Bool, DB> for bool {
158    fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
159        Ok(bytes.as_bytes().iter().any(|x| *x != 0))
160    }
161}
162
163impl<DB: MysqlLikeBackend> ToSql<sql_types::SmallInt, DB> for i16 {
164    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
165        out.write_i16::<NativeEndian>(*self)
166            .map(|_| IsNull::No)
167            .map_err(|e| Box::new(e) as Box<_>)
168    }
169}
170
171impl<DB: MysqlLikeBackend> ToSql<sql_types::Integer, DB> for i32 {
172    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
173        out.write_i32::<NativeEndian>(*self)
174            .map(|_| IsNull::No)
175            .map_err(|e| Box::new(e) as Box<_>)
176    }
177}
178
179impl<DB: MysqlLikeBackend> ToSql<sql_types::BigInt, DB> for i64 {
180    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
181        out.write_i64::<NativeEndian>(*self)
182            .map(|_| IsNull::No)
183            .map_err(|e| Box::new(e) as Box<_>)
184    }
185}
186
187impl<DB: MysqlLikeBackend> ToSql<sql_types::Double, DB> for f64 {
188    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
189        out.write_f64::<NativeEndian>(*self)
190            .map(|_| IsNull::No)
191            .map_err(|e| Box::new(e) as Box<_>)
192    }
193}
194
195impl<DB: MysqlLikeBackend> ToSql<sql_types::Float, DB> for f32 {
196    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
197        out.write_f32::<NativeEndian>(*self)
198            .map(|_| IsNull::No)
199            .map_err(|e| Box::new(e) as Box<_>)
200    }
201}
202
203impl<DB: MysqlLikeBackend> HasSqlType<Unsigned<TinyInt>> for DB {
204    fn metadata(_lookup: &mut ()) -> MysqlType {
205        MysqlType::UnsignedTiny
206    }
207}
208
209impl<DB: MysqlLikeBackend> HasSqlType<Unsigned<SmallInt>> for DB {
210    fn metadata(_lookup: &mut ()) -> MysqlType {
211        MysqlType::UnsignedShort
212    }
213}
214
215impl<DB: MysqlLikeBackend> HasSqlType<Unsigned<Integer>> for DB {
216    fn metadata(_lookup: &mut ()) -> MysqlType {
217        MysqlType::UnsignedLong
218    }
219}
220
221impl<DB: MysqlLikeBackend> HasSqlType<Unsigned<BigInt>> for DB {
222    fn metadata(_lookup: &mut ()) -> MysqlType {
223        MysqlType::UnsignedLongLong
224    }
225}
226
227/// Represents the MySQL datetime type.
228///
229/// ### [`ToSql`] impls
230///
231/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
232/// - [`time::PrimitiveDateTime`] with `feature = "time"`
233/// - [`time::OffsetDateTime`] with `feature = "time"`
234///
235/// ### [`FromSql`] impls
236///
237/// - [`chrono::NaiveDateTime`] with `feature = "chrono"`
238/// - [`time::PrimitiveDateTime`] with `feature = "time"`
239/// - [`time::OffsetDateTime`] with `feature = "time"`
240///
241/// [`ToSql`]: crate::serialize::ToSql
242/// [`FromSql`]: crate::deserialize::FromSql
243#[cfg_attr(
244    feature = "chrono",
245    doc = " [`chrono::NaiveDateTime`]: chrono::naive::NaiveDateTime"
246)]
247#[cfg_attr(
248    not(feature = "chrono"),
249    doc = " [`chrono::NaiveDateTime`]: https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveDateTime.html"
250)]
251#[cfg_attr(
252    feature = "time",
253    doc = " [`time::PrimitiveDateTime`]: time::PrimitiveDateTime"
254)]
255#[cfg_attr(
256    not(feature = "time"),
257    doc = " [`time::PrimitiveDateTime`]: https://docs.rs/time/0.3.9/time/struct.PrimitiveDateTime.html"
258)]
259#[cfg_attr(
260    feature = "time",
261    doc = " [`time::OffsetDateTime`]: time::OffsetDateTime"
262)]
263#[cfg_attr(
264    not(feature = "time"),
265    doc = " [`time::OffsetDateTime`]: https://docs.rs/time/0.3.9/time/struct.OffsetDateTime.html"
266)]
267#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Datetime {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Datetime")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Datetime {
    #[inline]
    fn clone(&self) -> Datetime { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Datetime { }Copy, #[automatically_derived]
impl ::core::default::Default for Datetime {
    #[inline]
    fn default() -> Datetime { Datetime {} }
}Default, const _: () =
    {
        use diesel;
        #[allow(non_camel_case_types)]
        impl diesel::query_builder::QueryId for Datetime {
            type QueryId = Datetime<>;
            const HAS_STATIC_QUERY_ID: bool = true;
            const IS_WINDOW_FUNCTION: bool = false;
        }
    };QueryId, const _: () =
    {
        use diesel;
        impl diesel::sql_types::SqlType for Datetime {
            type IsNull = diesel::sql_types::is_nullable::NotNull;
            const IS_ARRAY: bool = false;
        }
        impl diesel::sql_types::SingleValue for Datetime {}
        impl diesel::sql_types::HasSqlType<Datetime> for diesel::mysql::Mysql
            {
            fn metadata(_: &mut ()) -> diesel::mysql::MysqlType {
                diesel::mysql::MysqlType::DateTime
            }
        }
        impl diesel::sql_types::HasSqlType<Datetime> for
            diesel::mariadb::Mariadb {
            fn metadata(_: &mut ()) -> diesel::mariadb::MariadbType {
                diesel::mariadb::MariadbType::DateTime
            }
        }
    };SqlType)]
268#[diesel(mysql_type(name = "DateTime"))]
269#[diesel(mariadb_type(name = "DateTime"))]
270pub struct Datetime;