summaryrefslogtreecommitdiffstats
path: root/vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs')
-rw-r--r--vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs201
1 files changed, 201 insertions, 0 deletions
diff --git a/vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs b/vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs
new file mode 100644
index 000000000..4d62deeb7
--- /dev/null
+++ b/vendor/hashbrown-0.12.3/src/external_trait_impls/serde.rs
@@ -0,0 +1,201 @@
+mod size_hint {
+ use core::cmp;
+
+ /// This presumably exists to prevent denial of service attacks.
+ ///
+ /// Original discussion: https://github.com/serde-rs/serde/issues/1114.
+ #[cfg_attr(feature = "inline-more", inline)]
+ pub(super) fn cautious(hint: Option<usize>) -> usize {
+ cmp::min(hint.unwrap_or(0), 4096)
+ }
+}
+
+mod map {
+ use core::fmt;
+ use core::hash::{BuildHasher, Hash};
+ use core::marker::PhantomData;
+ use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
+ use serde::ser::{Serialize, Serializer};
+
+ use crate::hash_map::HashMap;
+
+ use super::size_hint;
+
+ impl<K, V, H> Serialize for HashMap<K, V, H>
+ where
+ K: Serialize + Eq + Hash,
+ V: Serialize,
+ H: BuildHasher,
+ {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(self)
+ }
+ }
+
+ impl<'de, K, V, S> Deserialize<'de> for HashMap<K, V, S>
+ where
+ K: Deserialize<'de> + Eq + Hash,
+ V: Deserialize<'de>,
+ S: BuildHasher + Default,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, V, S> {
+ marker: PhantomData<HashMap<K, V, S>>,
+ }
+
+ impl<'de, K, V, S> Visitor<'de> for MapVisitor<K, V, S>
+ where
+ K: Deserialize<'de> + Eq + Hash,
+ V: Deserialize<'de>,
+ S: BuildHasher + Default,
+ {
+ type Value = HashMap<K, V, S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut values = HashMap::with_capacity_and_hasher(
+ size_hint::cautious(map.size_hint()),
+ S::default(),
+ );
+
+ while let Some((key, value)) = map.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = MapVisitor {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+}
+
+mod set {
+ use core::fmt;
+ use core::hash::{BuildHasher, Hash};
+ use core::marker::PhantomData;
+ use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
+ use serde::ser::{Serialize, Serializer};
+
+ use crate::hash_set::HashSet;
+
+ use super::size_hint;
+
+ impl<T, H> Serialize for HashSet<T, H>
+ where
+ T: Serialize + Eq + Hash,
+ H: BuildHasher,
+ {
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(self)
+ }
+ }
+
+ impl<'de, T, S> Deserialize<'de> for HashSet<T, S>
+ where
+ T: Deserialize<'de> + Eq + Hash,
+ S: BuildHasher + Default,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T, S> {
+ marker: PhantomData<HashSet<T, S>>,
+ }
+
+ impl<'de, T, S> Visitor<'de> for SeqVisitor<T, S>
+ where
+ T: Deserialize<'de> + Eq + Hash,
+ S: BuildHasher + Default,
+ {
+ type Value = HashSet<T, S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = HashSet::with_capacity_and_hasher(
+ size_hint::cautious(seq.size_hint()),
+ S::default(),
+ );
+
+ while let Some(value) = seq.next_element()? {
+ values.insert(value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ #[allow(clippy::missing_errors_doc)]
+ fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqInPlaceVisitor<'a, T, S>(&'a mut HashSet<T, S>);
+
+ impl<'a, 'de, T, S> Visitor<'de> for SeqInPlaceVisitor<'a, T, S>
+ where
+ T: Deserialize<'de> + Eq + Hash,
+ S: BuildHasher + Default,
+ {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[cfg_attr(feature = "inline-more", inline)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ self.0.clear();
+ self.0.reserve(size_hint::cautious(seq.size_hint()));
+
+ while let Some(value) = seq.next_element()? {
+ self.0.insert(value);
+ }
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_seq(SeqInPlaceVisitor(place))
+ }
+ }
+}