mybatis_drive/types/
time_native.rs

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