mybatis_drive/types/
date_native.rs

1use std::any::type_name;
2use std::ops::{Deref, DerefMut};
3use std::str::FromStr;
4use rbson::Bson;
5use rbson::spec::BinarySubtype;
6use chrono::{Local, NaiveDate};
7use serde::{Deserializer, Serializer};
8use serde::de::Error;
9
10
11/// Rust type              Postgres type(s)
12/// chrono::NaiveDate      DATE
13#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
14pub struct DateNative {
15    pub inner: chrono::NaiveDate,
16}
17
18impl From<chrono::NaiveDate> for DateNative {
19    fn from(arg: chrono::NaiveDate) -> Self {
20        DateNative {
21            inner: arg
22        }
23    }
24}
25
26impl From<&chrono::NaiveDate> for DateNative {
27    fn from(arg: &chrono::NaiveDate) -> Self {
28        DateNative {
29            inner: arg.clone()
30        }
31    }
32}
33
34impl serde::Serialize for DateNative {
35    #[inline]
36    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
37        use serde::ser::Error;
38        if type_name::<S::Error>().eq("rbson::ser::error::Error") {
39            return serializer.serialize_str(&format!("DateNative({})", self.inner));
40        }else{
41            return self.inner.serialize(serializer);
42        }
43    }
44}
45
46
47impl<'de> serde::Deserialize<'de> for DateNative {
48    #[inline]
49    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
50        match Bson::deserialize(deserializer)? {
51            Bson::String(s) => {
52                if s.starts_with("DateNative(") && s.ends_with(")") {
53                    let inner_data = &s["DateNative(".len()..(s.len() - 1)];
54                    return Ok(Self {
55                        inner: chrono::NaiveDate::from_str(inner_data).or_else(|e| Err(D::Error::custom(e.to_string())))?,
56                    });
57                } else {
58                    return Ok(Self {
59                        inner: chrono::NaiveDate::from_str(&s).or_else(|e| Err(D::Error::custom(e.to_string())))?,
60                    });
61                }
62            }
63            _ => {
64                Err(D::Error::custom("deserialize un supported bson type!"))
65            }
66        }
67    }
68}
69
70impl std::fmt::Display for DateNative {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        self.inner.fmt(f)
73    }
74}
75
76impl std::fmt::Debug for DateNative {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        self.inner.fmt(f)
79    }
80}
81
82impl Deref for DateNative {
83    type Target = chrono::NaiveDate;
84
85    fn deref(&self) -> &Self::Target {
86        &self.inner
87    }
88}
89
90impl DerefMut for DateNative {
91    fn deref_mut(&mut self) -> &mut Self::Target {
92        &mut self.inner
93    }
94}
95
96
97impl DateNative {
98    /// Returns a [`DateTime`] which corresponds to the current date and time.
99    pub fn now() -> DateNative {
100        let utc = Local::now();
101        Self {
102            inner: utc.date().naive_local(),
103        }
104    }
105
106    /// create from str
107    pub fn from_str(arg: &str) -> Result<Self, crate::error::Error> {
108        let inner = chrono::NaiveDate::from_str(arg)?;
109        Ok(Self {
110            inner: inner
111        })
112    }
113}
114
115
116#[cfg(test)]
117mod test {
118    use crate::types::DateNative;
119
120    #[test]
121    fn test_ser_de() {
122        let b = DateNative::now();
123        let bsons = rbson::to_bson(&b).unwrap();
124        let b_de: DateNative = rbson::from_bson(bsons).unwrap();
125        assert_eq!(b, b_de);
126    }
127}