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