/// Serialization and deserialization. /// /// By default, serialization and deserialization go through Julid's big-endian /// bytes representation. use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; use crate::Julid; impl Serialize for Julid { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_bytes(&self.as_bytes()) } } struct JulidVisitor; impl<'de> Visitor<'de> for JulidVisitor { type Value = Julid; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("16 bytes") } fn visit_bytes(self, v: &[u8]) -> Result where E: serde::de::Error, { match std::convert::TryInto::<[u8; 16]>::try_into(v) { Ok(v) => Ok(v.into()), Err(_) => Err(serde::de::Error::invalid_length(v.len(), &self)), } } fn visit_byte_buf(self, v: Vec) -> Result where E: serde::de::Error, { let len = v.len(); match std::convert::TryInto::<[u8; 16]>::try_into(v) { Ok(v) => Ok(v.into()), Err(_) => Err(serde::de::Error::invalid_length(len, &self)), } } fn visit_seq(self, mut seq: A) -> Result where A: serde::de::SeqAccess<'de>, { let mut bytes = [0u8; 16]; let size = seq.size_hint().unwrap_or(0); let mut count = 0; while let Some(val) = seq.next_element()? { if count > 15 { break; } bytes[count] = val; count += 1; } if count != 16 || size > 16 { let sz = if count < 16 { count } else { size }; Err(serde::de::Error::invalid_length(sz, &self)) } else { Ok(bytes.into()) } } } impl<'de> Deserialize<'de> for Julid { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_bytes(JulidVisitor) } } /// Serialization and deserialization of Julids through their string /// representation. /// /// To use it, annotate a field with /// `#[serde(with = "julid_as_str")]`, /// `#[serde(serialize_with = "julid_as_str")]`, or /// `#[serde(deserialize_with = "julid_as_str")]`. /// /// # Examples /// ``` /// # use julid::Julid; /// # use julid::serde::julid_as_str; /// # use serde::{Serialize, Deserialize}; /// #[derive(Serialize, Deserialize)] /// struct StrExample { /// #[serde(with = "julid_as_str")] /// identifier: Julid /// } /// ``` pub mod julid_as_str { use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::Julid; pub fn serialize(value: &Julid, serializer: S) -> Result where S: Serializer, { let text = value.to_string(); text.serialize(serializer) } pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let deserialized_str = String::deserialize(deserializer)?; Julid::from_string(&deserialized_str).map_err(serde::de::Error::custom) } }