1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use super::protocol::Timestamp;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;

pub fn serialize_id<S: serde::Serializer>(
    uuid: &uuid::Uuid,
    serializer: S,
) -> Result<S::Ok, S::Error> {
    serializer.serialize_some(&uuid.as_simple().to_string())
}

pub mod ts_rfc3339 {
    use super::*;
    use serde::{de, ser};
    use std::fmt;

    pub fn serialize<S>(st: &Timestamp, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        let d = time::Duration::milliseconds(st.0 as i64);
        match OffsetDateTime::UNIX_EPOCH
            .checked_add(d)
            .and_then(|dt| dt.format(&Rfc3339).ok())
        {
            Some(formatted) => serializer.serialize_str(&formatted),
            None => Err(ser::Error::custom(format!(
                "invalid `Timestamp` instance: {:?}",
                st
            ))),
        }
    }

    pub(super) struct Rfc3339Deserializer;

    impl<'de> de::Visitor<'de> for Rfc3339Deserializer {
        type Value = Timestamp;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            write!(formatter, "an RFC3339 timestamp")
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            let dt = OffsetDateTime::parse(v, &Rfc3339).map_err(|e| E::custom(format!("{}", e)))?;
            let secs =
                u64::try_from(dt.unix_timestamp()).map_err(|e| E::custom(format!("{}", e)))?;
            Ok(Timestamp::from_secs(secs))
        }
    }
}

pub mod ts_rfc3339_opt {
    use super::*;
    use serde::ser;

    pub fn serialize<S>(st: &Option<Timestamp>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        match st {
            Some(st) => ts_rfc3339::serialize(st, serializer),
            None => serializer.serialize_none(),
        }
    }
}

// Functions
pub fn hex_lower(data: &[u8]) -> String {
    data.iter().map(|x| format!("{:02x}", x)).collect()
}