proto_types/timestamp/
serde.rs

1use std::fmt;
2
3use chrono::{DateTime, Utc};
4use serde::{de, ser};
5
6use crate::Timestamp;
7
8impl ser::Serialize for Timestamp {
9  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
10  where
11    S: ser::Serializer,
12  {
13    let mut ts_normalized = *self;
14    ts_normalized.normalize();
15
16    let datetime_opt =
17      DateTime::<Utc>::from_timestamp(ts_normalized.seconds, ts_normalized.nanos as u32);
18
19    if let Some(datetime) = datetime_opt {
20      let rfc3339_string = datetime.to_rfc3339();
21      serializer.serialize_str(&rfc3339_string)
22    } else {
23      Err(ser::Error::custom(format!(
24        "Invalid timestamp during serialization: seconds={}, nanos={}",
25        ts_normalized.seconds, ts_normalized.nanos
26      )))
27    }
28  }
29}
30
31impl<'de> de::Deserialize<'de> for Timestamp {
32  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
33  where
34    D: de::Deserializer<'de>,
35  {
36    struct TimestampVisitor;
37
38    impl de::Visitor<'_> for TimestampVisitor {
39      type Value = Timestamp;
40
41      fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
42        formatter.write_str("an RFC 3339 formatted timestamp string")
43      }
44
45      fn visit_str<E>(self, value: &str) -> Result<Timestamp, E>
46      where
47        E: de::Error,
48      {
49        let datetime = value
50          .parse::<DateTime<Utc>>()
51          .map_err(|e| de::Error::custom(format!("Invalid timestamp string format: {}", e)))?;
52
53        let prost_timestamp = Timestamp {
54          seconds: datetime.timestamp(),
55          nanos: datetime.timestamp_subsec_nanos() as i32,
56        };
57
58        Ok(prost_timestamp)
59      }
60    }
61
62    deserializer.deserialize_str(TimestampVisitor)
63  }
64}