julid/
serde.rs

1/// Serialization and deserialization.
2///
3/// By default, serialization and deserialization go through Julid's big-endian
4/// bytes representation.
5use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
6
7use crate::Julid;
8
9impl Serialize for Julid {
10    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
11    where
12        S: Serializer,
13    {
14        serializer.serialize_bytes(&self.as_bytes())
15    }
16}
17
18struct JulidVisitor;
19
20impl<'de> Visitor<'de> for JulidVisitor {
21    type Value = Julid;
22
23    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
24        formatter.write_str("16 bytes")
25    }
26
27    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
28    where
29        E: serde::de::Error,
30    {
31        match std::convert::TryInto::<[u8; 16]>::try_into(v) {
32            Ok(v) => Ok(v.into()),
33            Err(_) => Err(serde::de::Error::invalid_length(v.len(), &self)),
34        }
35    }
36
37    #[cfg(feature = "std")]
38    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
39    where
40        E: serde::de::Error,
41    {
42        let len = v.len();
43        match std::convert::TryInto::<[u8; 16]>::try_into(v) {
44            Ok(v) => Ok(v.into()),
45            Err(_) => Err(serde::de::Error::invalid_length(len, &self)),
46        }
47    }
48
49    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
50    where
51        A: serde::de::SeqAccess<'de>,
52    {
53        let mut bytes = [0u8; 16];
54        let size = seq.size_hint().unwrap_or(0);
55        let mut count = 0;
56        while let Some(val) = seq.next_element()? {
57            if count > 15 {
58                break;
59            }
60            bytes[count] = val;
61            count += 1;
62        }
63        if count != 16 || size > 16 {
64            let sz = if count < 16 { count } else { size };
65            Err(serde::de::Error::invalid_length(sz, &self))
66        } else {
67            Ok(bytes.into())
68        }
69    }
70}
71
72impl<'de> Deserialize<'de> for Julid {
73    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
74    where
75        D: Deserializer<'de>,
76    {
77        deserializer.deserialize_bytes(JulidVisitor)
78    }
79}
80
81/// Serialization and deserialization of Julids through their string
82/// representation.
83///
84/// To use it, annotate a field with
85/// `#[serde(with = "julid_as_str")]`,
86/// `#[serde(serialize_with = "julid_as_str")]`, or
87/// `#[serde(deserialize_with = "julid_as_str")]`.
88///
89/// # Examples
90/// ```
91/// # use julid::Julid;
92/// # use julid::serde::julid_as_str;
93/// # use serde::{Serialize, Deserialize};
94/// #[derive(Serialize, Deserialize)]
95/// struct StrExample {
96///     #[serde(with = "julid_as_str")]
97///     identifier: Julid
98/// }
99/// ```
100pub mod julid_as_str {
101    #[cfg(feature = "std")]
102    use serde::{Deserialize, Deserializer};
103    use serde::{Serialize, Serializer};
104
105    use crate::Julid;
106
107    /// Serialize a Julid into a String
108    pub fn serialize<S>(value: &Julid, serializer: S) -> Result<S::Ok, S::Error>
109    where
110        S: Serializer,
111    {
112        let text = value.to_string();
113        text.serialize(serializer)
114    }
115
116    #[cfg(feature = "std")]
117    /// Deserialize a String into a Julid (feature `std` only)
118    pub fn deserialize<'de, D>(deserializer: D) -> Result<Julid, D::Error>
119    where
120        D: Deserializer<'de>,
121    {
122        let deserialized_str = String::deserialize(deserializer)?;
123        Julid::from_str(&deserialized_str).map_err(serde::de::Error::custom)
124    }
125}