1use crate::{
2 DefaultHashBuilder, IdHashItem, IdHashMap,
3 support::{
4 alloc::{Allocator, Global},
5 size_hint::cautious,
6 },
7};
8use core::{fmt, hash::BuildHasher, marker::PhantomData};
9use serde_core::{
10 Deserialize, Deserializer, Serialize, Serializer,
11 de::{MapAccess, SeqAccess, Visitor},
12 ser::SerializeMap,
13};
14
15impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> Serialize
70 for IdHashMap<T, S, A>
71where
72 T: Serialize,
73{
74 fn serialize<Ser: Serializer>(
75 &self,
76 serializer: Ser,
77 ) -> Result<Ser::Ok, Ser::Error> {
78 self.items.serialize(serializer)
81 }
82}
83
84impl<
94 'de,
95 T: IdHashItem + fmt::Debug,
96 S: Clone + BuildHasher + Default,
97 A: Default + Clone + Allocator,
98> Deserialize<'de> for IdHashMap<T, S, A>
99where
100 T: Deserialize<'de>,
101{
102 fn deserialize<D: Deserializer<'de>>(
103 deserializer: D,
104 ) -> Result<Self, D::Error> {
105 deserializer.deserialize_any(SeqVisitor {
106 _marker: PhantomData,
107 hasher: S::default(),
108 alloc: A::default(),
109 })
110 }
111}
112
113impl<
114 'de,
115 T: IdHashItem + fmt::Debug + Deserialize<'de>,
116 S: Clone + BuildHasher,
117 A: Clone + Allocator,
118> IdHashMap<T, S, A>
119{
120 pub fn deserialize_in<D: Deserializer<'de>>(
123 deserializer: D,
124 alloc: A,
125 ) -> Result<Self, D::Error>
126 where
127 S: Default,
128 {
129 deserializer.deserialize_any(SeqVisitor {
130 _marker: PhantomData,
131 hasher: S::default(),
132 alloc,
133 })
134 }
135
136 pub fn deserialize_with_hasher<D: Deserializer<'de>>(
139 deserializer: D,
140 hasher: S,
141 ) -> Result<Self, D::Error>
142 where
143 A: Default,
144 {
145 deserializer.deserialize_any(SeqVisitor {
146 _marker: PhantomData,
147 hasher,
148 alloc: A::default(),
149 })
150 }
151
152 pub fn deserialize_with_hasher_in<D: Deserializer<'de>>(
155 deserializer: D,
156 hasher: S,
157 alloc: A,
158 ) -> Result<Self, D::Error> {
159 deserializer.deserialize_any(SeqVisitor {
161 _marker: PhantomData,
162 hasher,
163 alloc,
164 })
165 }
166}
167
168struct SeqVisitor<T, S, A> {
169 _marker: PhantomData<fn() -> T>,
170 hasher: S,
171 alloc: A,
172}
173
174impl<'de, T, S, A> Visitor<'de> for SeqVisitor<T, S, A>
175where
176 T: IdHashItem + Deserialize<'de> + fmt::Debug,
177 S: Clone + BuildHasher,
178 A: Clone + Allocator,
179{
180 type Value = IdHashMap<T, S, A>;
181
182 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
183 formatter
184 .write_str("a sequence or map of items representing an IdHashMap")
185 }
186
187 fn visit_seq<Access>(
188 self,
189 mut seq: Access,
190 ) -> Result<Self::Value, Access::Error>
191 where
192 Access: SeqAccess<'de>,
193 {
194 let mut map = IdHashMap::with_capacity_and_hasher_in(
195 cautious::<T>(seq.size_hint()),
196 self.hasher,
197 self.alloc,
198 );
199
200 while let Some(element) = seq.next_element()? {
201 map.insert_unique(element)
202 .map_err(serde_core::de::Error::custom)?;
203 }
204
205 Ok(map)
206 }
207
208 fn visit_map<Access>(
209 self,
210 mut map_access: Access,
211 ) -> Result<Self::Value, Access::Error>
212 where
213 Access: MapAccess<'de>,
214 {
215 let mut map = IdHashMap::with_capacity_and_hasher_in(
216 cautious::<T>(map_access.size_hint()),
217 self.hasher,
218 self.alloc,
219 );
220
221 while let Some((_, value)) =
222 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
223 {
224 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
225 }
226
227 Ok(map)
228 }
229}
230
231pub struct IdHashMapAsMap<T, S = DefaultHashBuilder, A: Allocator = Global> {
272 #[expect(clippy::type_complexity)]
273 _marker: PhantomData<fn() -> (T, S, A)>,
274}
275
276struct MapVisitorAsMap<T, S, A> {
277 _marker: PhantomData<fn() -> T>,
278 hasher: S,
279 alloc: A,
280}
281
282impl<'de, T, S, A> Visitor<'de> for MapVisitorAsMap<T, S, A>
283where
284 T: IdHashItem + Deserialize<'de> + fmt::Debug,
285 S: Clone + BuildHasher,
286 A: Clone + Allocator,
287{
288 type Value = IdHashMap<T, S, A>;
289
290 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
291 formatter.write_str("a map with items representing an IdHashMap")
292 }
293
294 fn visit_map<Access>(
295 self,
296 mut map_access: Access,
297 ) -> Result<Self::Value, Access::Error>
298 where
299 Access: MapAccess<'de>,
300 {
301 let mut map = IdHashMap::with_capacity_and_hasher_in(
302 cautious::<T>(map_access.size_hint()),
303 self.hasher,
304 self.alloc,
305 );
306
307 while let Some((_, value)) =
308 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
309 {
310 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
311 }
312
313 Ok(map)
314 }
315}
316
317impl<T, S, A> IdHashMapAsMap<T, S, A>
318where
319 S: Clone + BuildHasher,
320 A: Allocator,
321{
322 pub fn serialize<'a, Ser>(
324 map: &IdHashMap<T, S, A>,
325 serializer: Ser,
326 ) -> Result<Ser::Ok, Ser::Error>
327 where
328 T: 'a + IdHashItem + Serialize,
329 T::Key<'a>: Serialize,
330 Ser: Serializer,
331 {
332 let mut ser_map = serializer.serialize_map(Some(map.len()))?;
333 for item in map.iter() {
334 let key = item.key();
335 let key1 =
346 unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
347 ser_map.serialize_entry(&key1, item)?;
348 }
349 ser_map.end()
350 }
351
352 pub fn deserialize<'de, D>(
354 deserializer: D,
355 ) -> Result<IdHashMap<T, S, A>, D::Error>
356 where
357 T: IdHashItem + Deserialize<'de> + fmt::Debug,
358 S: Default,
359 A: Clone + Default,
360 D: Deserializer<'de>,
361 {
362 deserializer.deserialize_map(MapVisitorAsMap {
363 _marker: PhantomData,
364 hasher: S::default(),
365 alloc: A::default(),
366 })
367 }
368}