1use chrono::{NaiveDate, NaiveDateTime, NaiveTime, TimeDelta};
2use diesel::{
3 deserialize::{FromSql, Result as DeserializeResult},
4 serialize::{IsNull, Output, Result as SerializeResult, ToSql},
5 sql_types::{Date as SqlDate, Interval, Time, Timestamp as SqlTimestamp},
6};
7
8#[cfg(feature = "date")]
9use crate::Date;
10
11#[cfg(feature = "datetime")]
12use crate::DateTime;
13
14#[cfg(feature = "timeofday")]
15use crate::TimeOfDay;
16
17use crate::{Duration, Timestamp};
18
19#[cfg(feature = "diesel-mysql")]
20mod diesel_mysql {
21
22 use diesel::{
23 mysql::{Mysql, MysqlValue},
24 sql_types::Datetime as MysqlDateTime,
25 };
26
27 use super::*;
28
29 #[cfg(feature = "timeofday")]
30 impl FromSql<Time, Mysql> for TimeOfDay {
31 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
32 let chrono_time: NaiveTime = FromSql::<Time, Mysql>::from_sql(bytes)?;
33 Ok(chrono_time.into())
34 }
35 }
36
37 impl FromSql<SqlTimestamp, Mysql> for Timestamp {
38 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
39 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Mysql>::from_sql(bytes)?;
40 Ok(chrono_datetime.into())
41 }
42 }
43
44 impl FromSql<MysqlDateTime, Mysql> for Timestamp {
45 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
46 let chrono_datetime: NaiveDateTime = FromSql::<MysqlDateTime, Mysql>::from_sql(bytes)?;
47 Ok(chrono_datetime.into())
48 }
49 }
50
51 #[cfg(feature = "datetime")]
52 impl FromSql<SqlTimestamp, Mysql> for DateTime {
53 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
54 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Mysql>::from_sql(bytes)?;
55 Ok(chrono_datetime.into())
56 }
57 }
58
59 #[cfg(feature = "datetime")]
60 impl FromSql<MysqlDateTime, Mysql> for DateTime {
61 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
62 let chrono_datetime: NaiveDateTime = FromSql::<MysqlDateTime, Mysql>::from_sql(bytes)?;
63 Ok(chrono_datetime.into())
64 }
65 }
66
67 #[cfg(feature = "date")]
68 impl FromSql<SqlDate, Mysql> for Date {
69 fn from_sql(bytes: MysqlValue<'_>) -> DeserializeResult<Self> {
70 let chrono_date: NaiveDate = FromSql::<SqlDate, Mysql>::from_sql(bytes)?;
71 Ok(chrono_date.into())
72 }
73 }
74
75 #[cfg(feature = "timeofday")]
76 impl ToSql<Time, Mysql> for TimeOfDay {
77 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
78 let chrono_time: NaiveTime = (*self).try_into()?;
79
80 ToSql::<Time, Mysql>::to_sql(&chrono_time, &mut out.reborrow())
81 }
82 }
83
84 impl ToSql<SqlTimestamp, Mysql> for Timestamp {
85 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
86 let chrono_datetime: NaiveDateTime = (*self).try_into()?;
87
88 ToSql::<SqlTimestamp, Mysql>::to_sql(&chrono_datetime, &mut out.reborrow())
89 }
90 }
91
92 impl ToSql<MysqlDateTime, Mysql> for Timestamp {
93 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
94 ToSql::<SqlTimestamp, Mysql>::to_sql(self, out)
95 }
96 }
97
98 #[cfg(feature = "datetime")]
99 impl ToSql<SqlTimestamp, Mysql> for DateTime {
100 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
101 let chrono_datetime: NaiveDateTime = self.clone().try_into()?;
102
103 ToSql::<SqlTimestamp, Mysql>::to_sql(&chrono_datetime, &mut out.reborrow())
104 }
105 }
106
107 #[cfg(feature = "datetime")]
108 impl ToSql<MysqlDateTime, Mysql> for DateTime {
109 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
110 ToSql::<SqlTimestamp, Mysql>::to_sql(self, out)
111 }
112 }
113
114 #[cfg(feature = "date")]
115 impl ToSql<SqlDate, Mysql> for Date {
116 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> SerializeResult {
117 let chrono_date: NaiveDate = (*self).try_into()?;
118
119 ToSql::<SqlDate, Mysql>::to_sql(&chrono_date, &mut out.reborrow())
120 }
121 }
122}
123
124#[cfg(feature = "diesel-postgres")]
125mod diesel_postgres {
126 use diesel::{
127 pg::{Pg, PgValue},
128 sql_types::Timestamptz,
129 };
130
131 use super::*;
132
133 impl FromSql<Interval, Pg> for Duration {
134 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
135 let chrono_duration: TimeDelta = FromSql::<Interval, Pg>::from_sql(bytes)?;
136 Ok(chrono_duration.into())
137 }
138 }
139
140 #[cfg(feature = "timeofday")]
141 impl FromSql<Time, Pg> for TimeOfDay {
142 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
143 let chrono_time: NaiveTime = FromSql::<Time, Pg>::from_sql(bytes)?;
144 Ok(chrono_time.into())
145 }
146 }
147
148 impl FromSql<SqlTimestamp, Pg> for Timestamp {
149 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
150 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Pg>::from_sql(bytes)?;
151 Ok(chrono_datetime.into())
152 }
153 }
154
155 impl FromSql<Timestamptz, Pg> for Timestamp {
156 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
157 let chrono_datetime: NaiveDateTime = FromSql::<Timestamptz, Pg>::from_sql(bytes)?;
158 Ok(chrono_datetime.into())
159 }
160 }
161
162 #[cfg(feature = "datetime")]
163 impl FromSql<SqlTimestamp, Pg> for DateTime {
164 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
165 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Pg>::from_sql(bytes)?;
166 Ok(chrono_datetime.into())
167 }
168 }
169
170 #[cfg(feature = "datetime")]
171 impl FromSql<Timestamptz, Pg> for DateTime {
172 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
173 let chrono_datetime: NaiveDateTime = FromSql::<Timestamptz, Pg>::from_sql(bytes)?;
174 Ok(chrono_datetime.into())
175 }
176 }
177
178 #[cfg(feature = "date")]
179 impl FromSql<SqlDate, Pg> for Date {
180 fn from_sql(bytes: PgValue<'_>) -> DeserializeResult<Self> {
181 let chrono_date: NaiveDate = FromSql::<SqlDate, Pg>::from_sql(bytes)?;
182 Ok(chrono_date.into())
183 }
184 }
185
186 impl ToSql<Interval, Pg> for Duration {
187 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
188 let chrono_duration: TimeDelta = (*self).try_into()?;
189
190 ToSql::<Interval, Pg>::to_sql(&chrono_duration, &mut out.reborrow())
191 }
192 }
193
194 #[cfg(feature = "timeofday")]
195 impl ToSql<Time, Pg> for TimeOfDay {
196 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
197 let chrono_time: NaiveTime = (*self).try_into()?;
198
199 ToSql::<Time, Pg>::to_sql(&chrono_time, &mut out.reborrow())
200 }
201 }
202
203 impl ToSql<SqlTimestamp, Pg> for Timestamp {
204 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
205 let chrono_datetime: NaiveDateTime = (*self).try_into()?;
206
207 ToSql::<SqlTimestamp, Pg>::to_sql(&chrono_datetime, &mut out.reborrow())
208 }
209 }
210
211 impl ToSql<Timestamptz, Pg> for Timestamp {
212 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
213 ToSql::<SqlTimestamp, Pg>::to_sql(self, out)
214 }
215 }
216
217 #[cfg(feature = "datetime")]
218 impl ToSql<SqlTimestamp, Pg> for DateTime {
219 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
220 let chrono_datetime: NaiveDateTime = self.clone().try_into()?;
221
222 ToSql::<SqlTimestamp, Pg>::to_sql(&chrono_datetime, &mut out.reborrow())
223 }
224 }
225
226 #[cfg(feature = "datetime")]
227 impl ToSql<Timestamptz, Pg> for DateTime {
228 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
229 ToSql::<SqlTimestamp, Pg>::to_sql(self, out)
230 }
231 }
232
233 #[cfg(feature = "date")]
234 impl ToSql<SqlDate, Pg> for Date {
235 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> SerializeResult {
236 let chrono_date: NaiveDate = (*self).try_into()?;
237
238 ToSql::<SqlDate, Pg>::to_sql(&chrono_date, &mut out.reborrow())
239 }
240 }
241}
242
243#[cfg(feature = "diesel-sqlite")]
244mod diesel_sqlite {
245 use crate::{String, ToString};
246 use diesel::{backend::Backend, sql_types::TimestamptzSqlite, sqlite::Sqlite};
247
248 use super::*;
249
250 const ENCODE_NAIVE_DATETIME_FORMAT: &str = "%F %T%.f";
251 const DATE_FORMAT: &str = "%F";
252 const ENCODE_TIME_FORMAT: &str = "%T%.f";
253
254 fn format_naive_datetime(value: NaiveDateTime) -> String {
255 value
256 .format(ENCODE_NAIVE_DATETIME_FORMAT)
257 .to_string()
258 }
259
260 #[cfg(feature = "timeofday")]
261 impl FromSql<Time, Sqlite> for TimeOfDay {
262 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
263 let chrono_time: NaiveTime = FromSql::<Time, Sqlite>::from_sql(value)?;
264 Ok(chrono_time.into())
265 }
266 }
267
268 impl FromSql<SqlTimestamp, Sqlite> for Timestamp {
269 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
270 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Sqlite>::from_sql(value)?;
271 Ok(chrono_datetime.into())
272 }
273 }
274
275 impl FromSql<TimestamptzSqlite, Sqlite> for Timestamp {
276 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
277 let chrono_datetime: NaiveDateTime =
278 FromSql::<TimestamptzSqlite, Sqlite>::from_sql(value)?;
279 Ok(chrono_datetime.into())
280 }
281 }
282
283 #[cfg(feature = "datetime")]
284 impl FromSql<SqlTimestamp, Sqlite> for DateTime {
285 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
286 let chrono_datetime: NaiveDateTime = FromSql::<SqlTimestamp, Sqlite>::from_sql(value)?;
287 Ok(chrono_datetime.into())
288 }
289 }
290
291 #[cfg(feature = "datetime")]
292 impl FromSql<TimestamptzSqlite, Sqlite> for DateTime {
293 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
294 let chrono_datetime: NaiveDateTime =
295 FromSql::<TimestamptzSqlite, Sqlite>::from_sql(value)?;
296 Ok(chrono_datetime.into())
297 }
298 }
299
300 #[cfg(feature = "date")]
301 impl FromSql<SqlDate, Sqlite> for Date {
302 fn from_sql(value: <Sqlite as Backend>::RawValue<'_>) -> DeserializeResult<Self> {
303 let chrono_date: NaiveDate = FromSql::<SqlDate, Sqlite>::from_sql(value)?;
304 Ok(chrono_date.into())
305 }
306 }
307
308 #[cfg(feature = "timeofday")]
309 impl ToSql<Time, Sqlite> for TimeOfDay {
310 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
311 let chrono_time: NaiveTime = (*self).try_into()?;
312
313 out.set_value(chrono_time.format(ENCODE_TIME_FORMAT).to_string());
314 Ok(IsNull::No)
315 }
316 }
317
318 impl ToSql<TimestamptzSqlite, Sqlite> for Timestamp {
319 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
320 let chrono_datetime: NaiveDateTime = (*self).try_into()?;
321
322 out.set_value(format_naive_datetime(chrono_datetime));
323 Ok(IsNull::No)
324 }
325 }
326
327 impl ToSql<SqlTimestamp, Sqlite> for Timestamp {
328 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
329 let chrono_datetime: NaiveDateTime = (*self).try_into()?;
330
331 out.set_value(format_naive_datetime(chrono_datetime));
332 Ok(IsNull::No)
333 }
334 }
335
336 #[cfg(feature = "datetime")]
337 impl ToSql<TimestamptzSqlite, Sqlite> for DateTime {
338 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
339 let chrono_datetime: NaiveDateTime = self.clone().try_into()?;
340
341 out.set_value(format_naive_datetime(chrono_datetime));
342 Ok(IsNull::No)
343 }
344 }
345
346 #[cfg(feature = "datetime")]
347 impl ToSql<SqlTimestamp, Sqlite> for DateTime {
348 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
349 let chrono_datetime: NaiveDateTime = self.clone().try_into()?;
350
351 out.set_value(format_naive_datetime(chrono_datetime));
352 Ok(IsNull::No)
353 }
354 }
355
356 #[cfg(feature = "date")]
357 impl ToSql<SqlDate, Sqlite> for Date {
358 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> SerializeResult {
359 let chrono_date: NaiveDate = (*self).try_into()?;
360
361 out.set_value(chrono_date.format(DATE_FORMAT).to_string());
362 Ok(IsNull::No)
363 }
364 }
365}