use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor}; use serde::ser::{Serialize, SerializeMap, SerializeTuple, Serializer}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::HashMap; use std::fmt; use super::{super::CRDT, DeltaVec, StrokeDelta, StrokeID}; impl Serialize for DeltaVec { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { struct DeltaVecSerWrapper<'a>(Vec<((usize, u8, usize), &'a StrokeDelta)>); impl<'a> Serialize for DeltaVecSerWrapper<'a> { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let mut map = serializer.serialize_map(Some(self.0.len()))?; for (k, v) in &self.0 { map.serialize_entry(k, v)?; } map.end() } } let mut buffer: Vec<((usize, u8, usize), &StrokeDelta)> = Vec::with_capacity(self.0.len()); let mut lut_tmp: HashMap<u128, usize> = HashMap::new(); let mut lut_out: Vec<u128> = Vec::new(); for (k, v) in &self.0 { let (user, active) = CRDT::canonicalise_uuid(k.user()); let id = match lut_tmp.entry(user) { Occupied(entry) => *entry.get(), Vacant(entry) => { let id = lut_out.len(); entry.insert(id); lut_out.push(user); id } }; buffer.push(((id, active, k.id()), v)); } let mut tuple = serializer.serialize_tuple(2)?; tuple.serialize_element(&lut_out)?; tuple.serialize_element(&DeltaVecSerWrapper(buffer))?; tuple.end() } } impl<'de> Deserialize<'de> for DeltaVec { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { struct DeltaVecDeWrapper<'a>(&'a Vec<u128>); impl<'de, 'a> DeserializeSeed<'de> for DeltaVecDeWrapper<'a> { type Value = HashMap<StrokeID, StrokeDelta>; fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> where D: Deserializer<'de>, { struct DeltaVecDeWrapperVisitor<'a>(&'a Vec<u128>); impl<'de, 'a> Visitor<'de> for DeltaVecDeWrapperVisitor<'a> { type Value = HashMap<StrokeID, StrokeDelta>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "struct DeltaVec") } fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> where M: MapAccess<'de>, { let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0)); while let Some(((id, active, idx), value)) = access.next_entry()?: Option<((usize, u8, usize), StrokeDelta)> { let user = match self.0.get(id) { Some(user) => user, None => { return Err(de::Error::custom( "invalid canonincal user lookup id", )) } }; map.insert( StrokeID::new(CRDT::decanonicalise_uuid(*user, active), idx), value, ); } Ok(map) } } deserializer.deserialize_map(DeltaVecDeWrapperVisitor(self.0)) } } struct DeltaVecVisitor; impl<'de> Visitor<'de> for DeltaVecVisitor { type Value = DeltaVec; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct DeltaVec") } fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error> where V: SeqAccess<'de>, { let lut_in: Vec<u128> = seq .next_element()? .ok_or_else(|| de::Error::invalid_length(0, &self))?; let deltas = seq .next_element_seed(DeltaVecDeWrapper(&lut_in))? .ok_or_else(|| de::Error::invalid_length(1, &self))?; Ok(DeltaVec(deltas)) } } deserializer.deserialize_tuple(2, DeltaVecVisitor) } }