diff options
Diffstat (limited to 'third_party/rust/slab/src/serde.rs')
-rw-r--r-- | third_party/rust/slab/src/serde.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/third_party/rust/slab/src/serde.rs b/third_party/rust/slab/src/serde.rs new file mode 100644 index 0000000000..894d59c119 --- /dev/null +++ b/third_party/rust/slab/src/serde.rs @@ -0,0 +1,62 @@ +use core::fmt; +use core::marker::PhantomData; + +use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeMap, Serializer}; + +use super::{builder::Builder, Slab}; + +impl<T> Serialize for Slab<T> +where + T: Serialize, +{ + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut map_serializer = serializer.serialize_map(Some(self.len()))?; + for (key, value) in self { + map_serializer.serialize_key(&key)?; + map_serializer.serialize_value(value)?; + } + map_serializer.end() + } +} + +struct SlabVisitor<T>(PhantomData<T>); + +impl<'de, T> Visitor<'de> for SlabVisitor<T> +where + T: Deserialize<'de>, +{ + type Value = Slab<T>; + + fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(fmt, "a map") + } + + fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> + where + A: MapAccess<'de>, + { + let mut builder = Builder::with_capacity(map.size_hint().unwrap_or(0)); + + while let Some((key, value)) = map.next_entry()? { + builder.pair(key, value) + } + + Ok(builder.build()) + } +} + +impl<'de, T> Deserialize<'de> for Slab<T> +where + T: Deserialize<'de>, +{ + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(SlabVisitor(PhantomData)) + } +} |