mybatis_drive/types/
timestamp.rs1use std::alloc::Layout;
2use std::ops::{Deref, DerefMut};
3use rbson::Bson;
4use serde::{Deserializer, Serializer};
5use serde::de::Error;
6use sqlx_core::types::time;
7
8#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
16pub struct Timestamp {
17 pub inner: time::OffsetDateTime,
18}
19
20impl From<time::OffsetDateTime> for Timestamp {
21 fn from(arg: time::OffsetDateTime) -> Self {
22 Self {
23 inner: arg
24 }
25 }
26}
27
28impl From<&time::OffsetDateTime> for Timestamp {
29 fn from(arg: &time::OffsetDateTime) -> Self {
30 Self {
31 inner: arg.clone()
32 }
33 }
34}
35
36impl serde::Serialize for Timestamp {
37 #[inline]
38 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
39 let bs = Timestamp::from_le_i64(self.inner.unix_timestamp());
40 return bs.serialize(serializer);
41 }
42}
43
44impl<'de> serde::Deserialize<'de> for Timestamp {
45 #[inline]
46 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
47 match Bson::deserialize(deserializer)? {
48 Bson::String(s) => {
49 return Ok(Self {
50 inner: time::OffsetDateTime::parse(&s, "%F %T %z").or_else(|e| Err(D::Error::custom(e.to_string())))?,
51 });
52 }
53 Bson::Int64(data) => {
54 return Ok(Timestamp::from_unix_timestamp(data));
55 }
56 Bson::Timestamp(data) => {
57 return Ok(Timestamp::from(data));
58 }
59 _ => {
60 Err(D::Error::custom("deserialize un supported bson type!"))
61 }
62 }
63 }
64}
65
66impl Timestamp {
67 pub fn as_timestamp(arg: &rbson::Timestamp) -> i64 {
68 let upper = (arg.time.to_le() as u64) << 32;
69 let lower = arg.increment.to_le() as u64;
70 (upper | lower) as i64
71 }
72
73 pub fn from_le_i64(val: i64) -> rbson::Timestamp {
74 let ts = val.to_le();
75 rbson::Timestamp {
76 time: ((ts as u64) >> 32) as u32,
77 increment: (ts & 0xFFFF_FFFF) as u32,
78 }
79 }
80}
81
82impl From<rbson::Timestamp> for Timestamp {
83 fn from(data: rbson::Timestamp) -> Self {
84 let offset = time::OffsetDateTime::from_unix_timestamp(Timestamp::as_timestamp(&data));
85 Self {
86 inner: offset
87 }
88 }
89}
90
91impl std::fmt::Display for Timestamp {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 self.inner.fmt(f)
94 }
95}
96
97impl std::fmt::Debug for Timestamp {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 self.inner.fmt(f)
100 }
101}
102
103impl Deref for Timestamp {
104 type Target = time::OffsetDateTime;
105
106 fn deref(&self) -> &Self::Target {
107 &self.inner
108 }
109}
110
111impl DerefMut for Timestamp {
112 fn deref_mut(&mut self) -> &mut Self::Target {
113 &mut self.inner
114 }
115}
116
117impl Timestamp {
118 pub fn from_str(arg: &str) -> Result<Self, crate::error::Error> {
128 let inner = time::OffsetDateTime::parse(arg, "%F %T %z")?;
129 Ok(Self {
130 inner: inner
131 })
132 }
133
134 pub fn timestamp_millis(&self) -> i64 {
135 self.inner.unix_timestamp()
136 }
137
138 pub fn from_unix_timestamp(arg: i64) -> Self {
139 Self {
140 inner: time::OffsetDateTime::from_unix_timestamp(arg)
141 }
142 }
143}
144
145
146#[cfg(test)]
147mod test {
148 use super::*;
149
150 }