diesel/mysql/types/date_and_time/
mod.rs

1use std::io::Write;
2use std::os::raw as libc;
3use std::{mem, slice};
4
5use crate::deserialize::{self, FromSql, FromSqlRow};
6use crate::expression::AsExpression;
7use crate::mysql::{Mysql, MysqlValue};
8use crate::serialize::{self, IsNull, Output, ToSql};
9use crate::sql_types::{Date, Datetime, Time, Timestamp};
10
11#[cfg(feature = "chrono")]
12mod chrono;
13#[cfg(feature = "time")]
14mod time;
15
16// This is a type from libmysqlclient
17// we have our own copy here to not break the
18// public API as soon as this type changes
19// in the mysqlclient-sys dependency
20/// Corresponding rust representation of the
21/// [MYSQL_TIME](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html)
22/// struct from libmysqlclient
23#[repr(C)]
24#[derive(Debug, Clone, Copy, AsExpression, FromSqlRow)]
25#[non_exhaustive]
26#[diesel(sql_type = Timestamp)]
27#[diesel(sql_type = Time)]
28#[diesel(sql_type = Date)]
29#[diesel(sql_type = Datetime)]
30pub struct MysqlTime {
31    /// [Year field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#af585231d3ed0bc2fa389856e61e15d4e)
32    pub year: libc::c_uint,
33    /// [Month field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#ad3e92bddbd9ccf2e50117bdd51c235a2)
34    pub month: libc::c_uint,
35    /// [Day field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#ad51088bd5ab4ddc02e62d778d71ed808)
36    pub day: libc::c_uint,
37    /// [Hour field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#a7717a9c4de23a22863fe9c20b0706274)
38    pub hour: libc::c_uint,
39    /// [Minute field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#acfad0dafd22da03a527c58fdebfa9d14)
40    pub minute: libc::c_uint,
41    /// [Second field](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#a4cceb29d1a457f2ea961ce0d893814da)
42    pub second: libc::c_uint,
43    /// [Microseconds](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#a2e0fddb071af25ff478d16dc5514ba71)
44    pub second_part: libc::c_ulong,
45    /// [Is this a negative timestamp](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#af13161fbff85e4fe0ec9cd49b6eac1b8)
46    pub neg: bool,
47    /// [Timestamp type](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#a5331236f9b527a6e6b5f23d7c8058665)
48    pub time_type: MysqlTimestampType,
49    /// [Time zone displacement specified is seconds](https://dev.mysql.com/doc/dev/mysql-server/latest/structMYSQL__TIME.html#a07f3c8e1989c9805ba919d2120c8fed4)
50    pub time_zone_displacement: libc::c_int,
51}
52
53impl MysqlTime {
54    /// Construct a new instance of [MysqlTime]
55    #[allow(clippy::too_many_arguments)]
56    pub fn new(
57        year: libc::c_uint,
58        month: libc::c_uint,
59        day: libc::c_uint,
60        hour: libc::c_uint,
61        minute: libc::c_uint,
62        second: libc::c_uint,
63        second_part: libc::c_ulong,
64        neg: bool,
65        time_type: MysqlTimestampType,
66        time_zone_displacement: libc::c_int,
67    ) -> Self {
68        Self {
69            year,
70            month,
71            day,
72            hour,
73            minute,
74            second,
75            second_part,
76            neg,
77            time_type,
78            time_zone_displacement,
79        }
80    }
81}
82
83// This is a type from libmysqlclient
84// we have our own copy here to not break the
85// public API as soon as this type changes
86// in the mysqlclient-sys dependency
87/// Rust representation of
88/// [enum_mysql_timestamp_type](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73)
89#[derive(PartialEq, Debug, Copy, Clone, Eq)]
90#[repr(transparent)]
91pub struct MysqlTimestampType(libc::c_int);
92
93impl MysqlTimestampType {
94    /// Rust representation of
95    /// [MYSQL_TIMESTAMP_NONE](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73ace26c6b7d67a27c905dbcd130b3bd807)
96    pub const MYSQL_TIMESTAMP_NONE: MysqlTimestampType = MysqlTimestampType(-2);
97    /// Rust representation of
98    /// [MYSQL_TIMESTAMP_ERROR](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73a3518624dcc1eaca8d816c52aa7528f72)
99    pub const MYSQL_TIMESTAMP_ERROR: MysqlTimestampType = MysqlTimestampType(-1);
100    /// Rust representation of
101    /// [MYSQL_TIMESTAMP_DATE](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73a9e0845dc169b1f0056d2ffa3780c3f4e)
102    pub const MYSQL_TIMESTAMP_DATE: MysqlTimestampType = MysqlTimestampType(0);
103    /// Rust representation of
104    /// [MYSQL_TIMESTAMP_DATETIME](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73a8f6d8f066ea6ea77280c6a0baf063ce1)
105    pub const MYSQL_TIMESTAMP_DATETIME: MysqlTimestampType = MysqlTimestampType(1);
106    /// Rust representation of
107    /// [MYSQL_TIMESTAMP_TIME](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73a283c50fa3c62a2e17ad5173442edbbb9)
108    pub const MYSQL_TIMESTAMP_TIME: MysqlTimestampType = MysqlTimestampType(2);
109    /// Rust representation of
110    /// [MYSQL_TIMESTAMP_DATETIME_TZ](https://dev.mysql.com/doc/dev/mysql-server/latest/mysql__time_8h.html#aa633db8da896a5a0cc00ffcfb7477e73a7afc91f565961eb5f3beebfebe7243a2)
111    pub const MYSQL_TIMESTAMP_DATETIME_TZ: MysqlTimestampType = MysqlTimestampType(3);
112}
113
114macro_rules! mysql_time_impls {
115    ($ty:ty) => {
116        #[cfg(feature = "mysql_backend")]
117        impl ToSql<$ty, Mysql> for MysqlTime {
118            #[allow(unsafe_code)] // pointer cast
119            fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result {
120                let bytes = unsafe {
121                    let bytes_ptr = self as *const MysqlTime as *const u8;
122                    slice::from_raw_parts(bytes_ptr, mem::size_of::<MysqlTime>())
123                };
124                out.write_all(bytes)?;
125                Ok(IsNull::No)
126            }
127        }
128
129        #[cfg(feature = "mysql_backend")]
130        impl FromSql<$ty, Mysql> for MysqlTime {
131            fn from_sql(value: MysqlValue<'_>) -> deserialize::Result<Self> {
132                value.time_value()
133            }
134        }
135    };
136}
137
138mysql_time_impls!(Datetime);
139mysql_time_impls!(Timestamp);
140mysql_time_impls!(Time);
141mysql_time_impls!(Date);