diesel_chrono_duration/
lib.rs1#![warn(missing_docs)]
11
12use diesel::backend::Backend;
13use diesel::deserialize::{self, FromSql};
14use diesel::query_builder::bind_collector::RawBytesBindCollector;
15use diesel::serialize::{self, Output, ToSql};
16use diesel::sql_types::BigInt;
17use diesel::{AsExpression, FromSqlRow};
18
19#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
22#[diesel(sql_type = BigInt)]
23pub struct ChronoDurationProxy(pub chrono::Duration);
24
25impl From<chrono::Duration> for ChronoDurationProxy {
26 fn from(duration: chrono::Duration) -> ChronoDurationProxy {
27 ChronoDurationProxy(duration)
28 }
29}
30
31impl AsRef<chrono::Duration> for ChronoDurationProxy {
32 fn as_ref(&self) -> &chrono::Duration {
33 &self.0
34 }
35}
36
37impl std::ops::Deref for ChronoDurationProxy {
38 type Target = chrono::Duration;
39
40 fn deref(&self) -> &Self::Target {
41 &self.0
42 }
43}
44
45impl<DB> ToSql<BigInt, DB> for ChronoDurationProxy
46where
47 i64: ToSql<BigInt, DB>,
48 for<'c> DB: Backend + Backend<BindCollector<'c> = RawBytesBindCollector<DB>>,
49{
50 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
51 if let Some(num_nanoseconds) = self.0.num_nanoseconds() {
52 num_nanoseconds.to_sql(&mut out.reborrow())
54 } else {
55 Err(format!("{:?} as nanoseconds is too large to fit in an i64", self).into())
56 }
57 }
58}
59
60impl<DB> FromSql<BigInt, DB> for ChronoDurationProxy
61where
62 i64: FromSql<BigInt, DB>,
63 DB: Backend,
64{
65 fn from_sql(value: DB::RawValue<'_>) -> deserialize::Result<Self> {
66 let i64_value = <i64 as FromSql<BigInt, DB>>::from_sql(value)?;
67 Ok(chrono::Duration::nanoseconds(i64_value).into())
68 }
69}