serde_firestore_value/typ/
timestamp.rs1#[derive(
32 Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize,
33)]
34#[serde(rename = "$__serde-firestore-value_private_timestamp")]
35pub struct Timestamp {
36 pub seconds: i64,
38 pub nanos: i32,
40}
41
42impl Timestamp {
43 pub(crate) const NAME: &'static str = "$__serde-firestore-value_private_timestamp";
44}
45
46impl From<Timestamp> for prost_types::Timestamp {
47 fn from(Timestamp { seconds, nanos }: Timestamp) -> Self {
48 Self { seconds, nanos }
49 }
50}
51
52impl From<prost_types::Timestamp> for Timestamp {
53 fn from(prost_types::Timestamp { seconds, nanos }: prost_types::Timestamp) -> Self {
54 Self { seconds, nanos }
55 }
56}
57
58#[cfg(feature = "chrono")]
59impl std::convert::TryFrom<Timestamp> for chrono::DateTime<chrono::Utc> {
60 type Error = crate::Error;
61
62 fn try_from(Timestamp { seconds, nanos }: Timestamp) -> Result<Self, Self::Error> {
63 let nanos = u32::try_from(nanos).map_err(|_| {
64 crate::Error::from(crate::error::ErrorCode::Custom(format!(
65 "chrono::DateTime::<chrono::Utc>::try_from(Timestamp) / u32::try_from({})",
66 nanos
67 )))
68 })?;
69 Self::from_timestamp(seconds, nanos).ok_or_else(|| {
70 crate::Error::from(crate::error::ErrorCode::Custom(format!(
71 "chrono::DateTime::<chrono::Utc>::try_from(Timestamp) / chrono::DateTime::<chrono::Utc>::from_timestamp({}, {})",
72 seconds, nanos
73 )))
74 })
75 }
76}
77
78#[cfg(feature = "time")]
79impl std::convert::TryFrom<Timestamp> for time::OffsetDateTime {
80 type Error = crate::Error;
81
82 fn try_from(Timestamp { seconds, nanos }: Timestamp) -> Result<Self, Self::Error> {
83 let timestamp_nanos = i128::from(seconds) * 1_000_000_000_i128 + i128::from(nanos);
84 Self::from_unix_timestamp_nanos(timestamp_nanos).map_err(|e| {
85 crate::Error::from(crate::error::ErrorCode::Custom(format!(
86 "time::OffsetDateTime::try_from(Tiemstamp) / time::OffsetDateTime::from_unix_timestamp_nanos({}) : {}",
87 timestamp_nanos,
88 e
89 )))
90 })
91 }
92}
93
94#[cfg(feature = "chrono")]
95impl std::convert::TryFrom<chrono::DateTime<chrono::Utc>> for Timestamp {
96 type Error = crate::Error;
97
98 fn try_from(date_time: chrono::DateTime<chrono::Utc>) -> Result<Self, Self::Error> {
99 let seconds = date_time.timestamp();
100 let nanos = date_time.timestamp_subsec_nanos();
101 let nanos = i32::try_from(nanos).map_err(|_| {
102 crate::Error::from(crate::error::ErrorCode::Custom(format!(
103 "Timestamp::try_from(chrono::DateTime::<chrono::Utc>) / i32::try_from({})",
104 nanos
105 )))
106 })?;
107 Ok(Self { seconds, nanos })
108 }
109}
110
111#[cfg(feature = "time")]
112impl std::convert::TryFrom<time::OffsetDateTime> for Timestamp {
113 type Error = crate::Error;
114
115 fn try_from(offset_date_time: time::OffsetDateTime) -> Result<Self, Self::Error> {
116 let seconds = offset_date_time.unix_timestamp();
117 let nanos = offset_date_time.unix_timestamp_nanos() % 1_000_000_000_i128;
118 let nanos = i32::try_from(nanos).map_err(|_| {
119 crate::Error::from(crate::error::ErrorCode::Custom(format!(
120 "Timestamp::try_from(chrono::DateTime::<chrono::Utc>) / i32::try_from({})",
121 nanos
122 )))
123 })?;
124 Ok(Self { seconds, nanos })
125 }
126}