mybatis_drive/types/
timestamp_z.rs1use std::alloc::Layout;
2use std::any::type_name;
3use std::ops::{Deref, DerefMut};
4use std::str::FromStr;
5use chrono::{NaiveDateTime, Utc};
6use rbson::Bson;
7use rbson::spec::BinarySubtype;
8use serde::{Deserializer, Serializer};
9use serde::de::Error;
10use sqlx_core::types::time;
11use crate::value::DateTimeNow;
12
13#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
17pub struct TimestampZ {
18 pub inner: chrono::DateTime<Utc>,
19}
20
21impl From<chrono::DateTime<Utc>> for TimestampZ {
22 fn from(arg: chrono::DateTime<Utc>) -> Self {
23 Self {
24 inner: arg
25 }
26 }
27}
28
29impl From<&chrono::DateTime<Utc>> for TimestampZ {
30 fn from(arg: &chrono::DateTime<Utc>) -> Self {
31 Self {
32 inner: arg.clone()
33 }
34 }
35}
36
37impl serde::Serialize for TimestampZ {
38 #[inline]
39 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
40 use serde::ser::Error;
41 if type_name::<S::Error>().eq("rbson::ser::error::Error") {
42 return serializer.serialize_str(&format!("TimestampZ({})", self.inner.to_string()));
43 }else{
44 return self.inner.serialize(serializer);
45 }
46 }
47}
48
49impl<'de> serde::Deserialize<'de> for TimestampZ {
50 #[inline]
51 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
52 match Bson::deserialize(deserializer)? {
53 Bson::String(s) => {
54 if s.starts_with("TimestampZ(") && s.ends_with(")") {
55 let inner_data = &s["TimestampZ(".len()..(s.len() - 1)];
56 return Ok(Self {
57 inner: {
58 match chrono::DateTime::from_str(inner_data){
59 Ok(v)=>{
60 Ok(v)
61 }
62 Err(e)=>{
63 log::error!("{}", e);
64 Err(D::Error::custom("parse TimestampZ fail"))
65 }
66 }
67 }?,
68 });
69 } else {
70 return Ok(Self {
71 inner:{
72 match chrono::DateTime::from_str(&s){
73 Ok(v)=>{
74 Ok(v)
75 }
76 Err(e)=>{
77 log::error!("{}", e);
78 Err(D::Error::custom("parse TimestampZ fail"))
79 }
80 }
81 }?,
82 });
83 }
84 }
85 _ => {
86 Err(D::Error::custom("deserialize un supported bson type!"))
87 }
88 }
89 }
90}
91
92impl TimestampZ {
93 pub fn as_timestamp(arg: &rbson::Timestamp) -> i64 {
94 let upper = (arg.time.to_le() as u64) << 32;
95 let lower = arg.increment.to_le() as u64;
96 (upper | lower) as i64
97 }
98
99 pub fn from_le_i64(val: i64) -> rbson::Timestamp {
100 let ts = val.to_le();
101 rbson::Timestamp {
102 time: ((ts as u64) >> 32) as u32,
103 increment: (ts & 0xFFFF_FFFF) as u32,
104 }
105 }
106}
107
108
109impl std::fmt::Display for TimestampZ {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 self.inner.fmt(f)
112 }
113}
114
115impl std::fmt::Debug for TimestampZ {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 self.inner.fmt(f)
118 }
119}
120
121impl Deref for TimestampZ {
122 type Target = chrono::DateTime<Utc>;
123
124 fn deref(&self) -> &Self::Target {
125 &self.inner
126 }
127}
128
129impl DerefMut for TimestampZ {
130 fn deref_mut(&mut self) -> &mut Self::Target {
131 &mut self.inner
132 }
133}
134
135impl TimestampZ {
136 pub fn now() -> Self {
137 Self {
138 inner: chrono::DateTime::from_utc(NaiveDateTime::now(),Utc)
139 }
140 }
141
142 pub fn now_utc() -> Self {
143 Self {
144 inner: chrono::DateTime::from_utc(NaiveDateTime::now(),Utc)
145 }
146 }
147
148 pub fn now_local() -> Self {
149 Self {
150 inner: chrono::DateTime::from_utc(NaiveDateTime::now(),Utc)
151 }
152 }
153
154 pub fn from_str(arg: &str) -> Result<Self, crate::error::Error> {
156 Ok(Self {
157 inner: chrono::DateTime::<Utc>::from_str(arg)?
158 })
159 }
160
161}
162
163#[cfg(test)]
164mod test {
165 use crate::types::TimestampZ;
166
167 #[test]
168 fn test_native() {
169 let dt = TimestampZ::now_utc();
170 let s = rbson::to_bson(&dt).unwrap();
171 let dt_new: TimestampZ = rbson::from_bson(s).unwrap();
172 println!("{},{}", dt.timestamp_millis(), dt_new.timestamp_millis());
173 assert_eq!(dt, dt_new);
174 }
175
176 #[test]
177 fn test_ser_de() {
178 let b = TimestampZ::now();
179 let bsons = rbson::to_bson(&b).unwrap();
180 let b_de: TimestampZ = rbson::from_bson(bsons).unwrap();
181 assert_eq!(b, b_de);
182 }
183
184 #[test]
185 fn test_str_de() {
186 let b = "2022-01-05 03:18:49 UTC".to_string();
187 let bsons = rbson::to_bson(&b).unwrap();
188 let b_de: TimestampZ = rbson::from_bson(bsons).unwrap();
189 }
191}