Skip to main content

proto_types/
diesel_impls.rs

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}