usesuper::LiteMap; usecrate::store::*; use core::fmt; use core::marker::PhantomData; use serde::de::{MapAccess, SeqAccess, Visitor}; use serde::{Deserialize, Deserializer};
#[cfg(feature = "serde")] use serde::{ser::SerializeMap, Serialize, Serializer};
#[cfg(feature = "serde")] impl<K, V, R> Serialize for LiteMap<K, V, R> where
K: Serialize,
V: Serialize,
R: Store<K, V> + Serialize,
{ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer,
{ // Many human-readable formats don't support values other // than numbers and strings as map keys. For them, we can serialize // as a vec of tuples instead if serializer.is_human_readable() { iflet Some((ref k, _)) = self.values.lm_get(0) { if !super::serde_helpers::is_num_or_string(k) { returnself.values.serialize(serializer);
} // continue to regular serialization
}
} letmut map = serializer.serialize_map(Some(self.len()))?; letmut i = 0; while i < self.values.lm_len() { #[allow(clippy::unwrap_used)] // i is in range let (k, v) = self.values.lm_get(i).unwrap();
map.serialize_entry(k, v)?;
i += 1;
}
map.end()
}
}
/// Modified example from https://serde.rs/deserialize-map.html #[allow(clippy::type_complexity)] struct LiteMapVisitor<K, V, R> {
marker: PhantomData<fn() -> LiteMap<K, V, R>>,
}
// While there are entries remaining in the input, add them // into our map. whilelet Some((key, value)) = access.next_element()? { // Try to append it at the end, hoping for a sorted map. // If not sorted, insert as usual. // This allows for arbitrary maps (e.g. from user JSON) // to be deserialized into LiteMap // without impacting performance in the case of deserializing // a serialized map that came from another LiteMap iflet Some((key, value)) = map.try_append(key, value) { // Note: this effectively selection sorts the map, // which isn't efficient for large maps
map.insert(key, value);
}
}
Ok(map)
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> where
M: MapAccess<'de>,
{ letmut map = LiteMap::with_capacity(access.size_hint().unwrap_or(0));
// While there are entries remaining in the input, add them // into our map. whilelet Some((key, value)) = access.next_entry()? { // Try to append it at the end, hoping for a sorted map. // If not sorted, insert as usual. // This allows for arbitrary maps (e.g. from user JSON) // to be deserialized into LiteMap // without impacting performance in the case of deserializing // a serialized map that came from another LiteMap iflet Some((key, value)) = map.try_append(key, value) { // Note: this effectively selection sorts the map, // which isn't efficient for large maps
map.insert(key, value);
}
}
Ok(map)
}
}
impl<'de, K, V, R> Deserialize<'de> for LiteMap<K, V, R> where
K: Ord + Deserialize<'de>,
V: Deserialize<'de>,
R: StoreMut<K, V> + StoreFromIterable<K, V>,
{ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
D: Deserializer<'de>,
{ if deserializer.is_human_readable() { // deserialize_any only works on self-describing (human-readable) // formats
deserializer.deserialize_any(LiteMapVisitor::new())
} else {
deserializer.deserialize_map(LiteMapVisitor::new())
}
}
}
#[cfg(test)] mod test { usecrate::LiteMap; use alloc::borrow::ToOwned; use alloc::string::String;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.