Skip to main content

diesel/mysql/types/
mod.rs

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