1 | #![cfg_attr (docsrs, doc(cfg(feature = "serde" )))] |
2 | |
3 | use serde::de::value::{MapDeserializer, SeqDeserializer}; |
4 | use serde::de::{ |
5 | Deserialize, Deserializer, Error, IntoDeserializer, MapAccess, SeqAccess, Visitor, |
6 | }; |
7 | use serde::ser::{Serialize, Serializer}; |
8 | |
9 | use core::fmt::{self, Formatter}; |
10 | use core::hash::{BuildHasher, Hash}; |
11 | use core::marker::PhantomData; |
12 | use core::{cmp, mem}; |
13 | |
14 | use crate::{Bucket, IndexMap, IndexSet}; |
15 | |
16 | /// Limit our preallocated capacity from a deserializer `size_hint()`. |
17 | /// |
18 | /// We do account for the `Bucket` overhead from its saved `hash` field, but we don't count the |
19 | /// `RawTable` allocation or the fact that its raw capacity will be rounded up to a power of two. |
20 | /// The "max" is an arbitrary choice anyway, not something that needs precise adherence. |
21 | /// |
22 | /// This is based on the internal `serde::de::size_hint::cautious(hint)` function. |
23 | pub(crate) fn cautious_capacity<K, V>(hint: Option<usize>) -> usize { |
24 | const MAX_PREALLOC_BYTES: usize = 1024 * 1024; |
25 | |
26 | cmp::min( |
27 | v1:hint.unwrap_or(0), |
28 | MAX_PREALLOC_BYTES / mem::size_of::<Bucket<K, V>>(), |
29 | ) |
30 | } |
31 | |
32 | impl<K, V, S> Serialize for IndexMap<K, V, S> |
33 | where |
34 | K: Serialize, |
35 | V: Serialize, |
36 | { |
37 | fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error> |
38 | where |
39 | T: Serializer, |
40 | { |
41 | serializer.collect_map(self) |
42 | } |
43 | } |
44 | |
45 | struct IndexMapVisitor<K, V, S>(PhantomData<(K, V, S)>); |
46 | |
47 | impl<'de, K, V, S> Visitor<'de> for IndexMapVisitor<K, V, S> |
48 | where |
49 | K: Deserialize<'de> + Eq + Hash, |
50 | V: Deserialize<'de>, |
51 | S: Default + BuildHasher, |
52 | { |
53 | type Value = IndexMap<K, V, S>; |
54 | |
55 | fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { |
56 | write!(formatter, "a map" ) |
57 | } |
58 | |
59 | fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> |
60 | where |
61 | A: MapAccess<'de>, |
62 | { |
63 | let capacity: usize = cautious_capacity::<K, V>(map.size_hint()); |
64 | let mut values: IndexMap = IndexMap::with_capacity_and_hasher(n:capacity, S::default()); |
65 | |
66 | while let Some((key: K, value: V)) = map.next_entry()? { |
67 | values.insert(key, value); |
68 | } |
69 | |
70 | Ok(values) |
71 | } |
72 | } |
73 | |
74 | impl<'de, K, V, S> Deserialize<'de> for IndexMap<K, V, S> |
75 | where |
76 | K: Deserialize<'de> + Eq + Hash, |
77 | V: Deserialize<'de>, |
78 | S: Default + BuildHasher, |
79 | { |
80 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
81 | where |
82 | D: Deserializer<'de>, |
83 | { |
84 | deserializer.deserialize_map(visitor:IndexMapVisitor(PhantomData)) |
85 | } |
86 | } |
87 | |
88 | impl<'de, K, V, S, E> IntoDeserializer<'de, E> for IndexMap<K, V, S> |
89 | where |
90 | K: IntoDeserializer<'de, E> + Eq + Hash, |
91 | V: IntoDeserializer<'de, E>, |
92 | S: BuildHasher, |
93 | E: Error, |
94 | { |
95 | type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>; |
96 | |
97 | fn into_deserializer(self) -> Self::Deserializer { |
98 | MapDeserializer::new(self.into_iter()) |
99 | } |
100 | } |
101 | |
102 | impl<T, S> Serialize for IndexSet<T, S> |
103 | where |
104 | T: Serialize, |
105 | { |
106 | fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error> |
107 | where |
108 | Se: Serializer, |
109 | { |
110 | serializer.collect_seq(self) |
111 | } |
112 | } |
113 | |
114 | struct IndexSetVisitor<T, S>(PhantomData<(T, S)>); |
115 | |
116 | impl<'de, T, S> Visitor<'de> for IndexSetVisitor<T, S> |
117 | where |
118 | T: Deserialize<'de> + Eq + Hash, |
119 | S: Default + BuildHasher, |
120 | { |
121 | type Value = IndexSet<T, S>; |
122 | |
123 | fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { |
124 | write!(formatter, "a set" ) |
125 | } |
126 | |
127 | fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> |
128 | where |
129 | A: SeqAccess<'de>, |
130 | { |
131 | let capacity: usize = cautious_capacity::<T, ()>(seq.size_hint()); |
132 | let mut values: IndexSet = IndexSet::with_capacity_and_hasher(n:capacity, S::default()); |
133 | |
134 | while let Some(value: T) = seq.next_element()? { |
135 | values.insert(value); |
136 | } |
137 | |
138 | Ok(values) |
139 | } |
140 | } |
141 | |
142 | impl<'de, T, S> Deserialize<'de> for IndexSet<T, S> |
143 | where |
144 | T: Deserialize<'de> + Eq + Hash, |
145 | S: Default + BuildHasher, |
146 | { |
147 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
148 | where |
149 | D: Deserializer<'de>, |
150 | { |
151 | deserializer.deserialize_seq(visitor:IndexSetVisitor(PhantomData)) |
152 | } |
153 | } |
154 | |
155 | impl<'de, T, S, E> IntoDeserializer<'de, E> for IndexSet<T, S> |
156 | where |
157 | T: IntoDeserializer<'de, E> + Eq + Hash, |
158 | S: BuildHasher, |
159 | E: Error, |
160 | { |
161 | type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>; |
162 | |
163 | fn into_deserializer(self) -> Self::Deserializer { |
164 | SeqDeserializer::new(self.into_iter()) |
165 | } |
166 | } |
167 | |