1use crate::{
2 DefaultHashBuilder, IdHashItem, IdHashMap,
3 support::alloc::{Allocator, Global},
4};
5use core::{fmt, hash::BuildHasher, marker::PhantomData};
6use serde_core::{
7 Deserialize, Deserializer, Serialize, Serializer,
8 de::{MapAccess, SeqAccess, Visitor},
9 ser::SerializeMap,
10};
11
12impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> Serialize
67 for IdHashMap<T, S, A>
68where
69 T: Serialize,
70{
71 fn serialize<Ser: Serializer>(
72 &self,
73 serializer: Ser,
74 ) -> Result<Ser::Ok, Ser::Error> {
75 self.items.serialize(serializer)
78 }
79}
80
81impl<
91 'de,
92 T: IdHashItem + fmt::Debug,
93 S: Clone + BuildHasher + Default,
94 A: Default + Clone + Allocator,
95> Deserialize<'de> for IdHashMap<T, S, A>
96where
97 T: Deserialize<'de>,
98{
99 fn deserialize<D: Deserializer<'de>>(
100 deserializer: D,
101 ) -> Result<Self, D::Error> {
102 deserializer.deserialize_any(SeqVisitor {
103 _marker: PhantomData,
104 hasher: S::default(),
105 alloc: A::default(),
106 })
107 }
108}
109
110impl<
111 'de,
112 T: IdHashItem + fmt::Debug + Deserialize<'de>,
113 S: Clone + BuildHasher,
114 A: Clone + Allocator,
115> IdHashMap<T, S, A>
116{
117 pub fn deserialize_in<D: Deserializer<'de>>(
120 deserializer: D,
121 alloc: A,
122 ) -> Result<Self, D::Error>
123 where
124 S: Default,
125 {
126 deserializer.deserialize_any(SeqVisitor {
127 _marker: PhantomData,
128 hasher: S::default(),
129 alloc,
130 })
131 }
132
133 pub fn deserialize_with_hasher<D: Deserializer<'de>>(
136 deserializer: D,
137 hasher: S,
138 ) -> Result<Self, D::Error>
139 where
140 A: Default,
141 {
142 deserializer.deserialize_any(SeqVisitor {
143 _marker: PhantomData,
144 hasher,
145 alloc: A::default(),
146 })
147 }
148
149 pub fn deserialize_with_hasher_in<D: Deserializer<'de>>(
152 deserializer: D,
153 hasher: S,
154 alloc: A,
155 ) -> Result<Self, D::Error> {
156 deserializer.deserialize_any(SeqVisitor {
158 _marker: PhantomData,
159 hasher,
160 alloc,
161 })
162 }
163}
164
165struct SeqVisitor<T, S, A> {
166 _marker: PhantomData<fn() -> T>,
167 hasher: S,
168 alloc: A,
169}
170
171impl<'de, T, S, A> Visitor<'de> for SeqVisitor<T, S, A>
172where
173 T: IdHashItem + Deserialize<'de> + fmt::Debug,
174 S: Clone + BuildHasher,
175 A: Clone + Allocator,
176{
177 type Value = IdHashMap<T, S, A>;
178
179 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
180 formatter
181 .write_str("a sequence or map of items representing an IdHashMap")
182 }
183
184 fn visit_seq<Access>(
185 self,
186 mut seq: Access,
187 ) -> Result<Self::Value, Access::Error>
188 where
189 Access: SeqAccess<'de>,
190 {
191 let mut map = match seq.size_hint() {
192 Some(size) => IdHashMap::with_capacity_and_hasher_in(
193 size,
194 self.hasher,
195 self.alloc,
196 ),
197 None => IdHashMap::with_hasher_in(self.hasher, 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 = match map_access.size_hint() {
216 Some(size) => IdHashMap::with_capacity_and_hasher_in(
217 size,
218 self.hasher,
219 self.alloc,
220 ),
221 None => IdHashMap::with_hasher_in(self.hasher, self.alloc),
222 };
223
224 while let Some((_, value)) =
225 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
226 {
227 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
228 }
229
230 Ok(map)
231 }
232}
233
234pub struct IdHashMapAsMap<T, S = DefaultHashBuilder, A: Allocator = Global> {
275 #[expect(clippy::type_complexity)]
276 _marker: PhantomData<fn() -> (T, S, A)>,
277}
278
279struct MapVisitorAsMap<T, S, A> {
280 _marker: PhantomData<fn() -> T>,
281 hasher: S,
282 alloc: A,
283}
284
285impl<'de, T, S, A> Visitor<'de> for MapVisitorAsMap<T, S, A>
286where
287 T: IdHashItem + Deserialize<'de> + fmt::Debug,
288 S: Clone + BuildHasher,
289 A: Clone + Allocator,
290{
291 type Value = IdHashMap<T, S, A>;
292
293 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
294 formatter.write_str("a map with items representing an IdHashMap")
295 }
296
297 fn visit_map<Access>(
298 self,
299 mut map_access: Access,
300 ) -> Result<Self::Value, Access::Error>
301 where
302 Access: MapAccess<'de>,
303 {
304 let mut map = match map_access.size_hint() {
305 Some(size) => IdHashMap::with_capacity_and_hasher_in(
306 size,
307 self.hasher,
308 self.alloc,
309 ),
310 None => IdHashMap::with_hasher_in(self.hasher, self.alloc),
311 };
312
313 while let Some((_, value)) =
314 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
315 {
316 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
317 }
318
319 Ok(map)
320 }
321}
322
323impl<T, S, A> IdHashMapAsMap<T, S, A>
324where
325 S: Clone + BuildHasher,
326 A: Allocator,
327{
328 pub fn serialize<'a, Ser>(
330 map: &IdHashMap<T, S, A>,
331 serializer: Ser,
332 ) -> Result<Ser::Ok, Ser::Error>
333 where
334 T: 'a + IdHashItem + Serialize,
335 T::Key<'a>: Serialize,
336 Ser: Serializer,
337 {
338 let mut ser_map = serializer.serialize_map(Some(map.len()))?;
339 for item in map.iter() {
340 let key = item.key();
341 let key1 =
352 unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
353 ser_map.serialize_entry(&key1, item)?;
354 }
355 ser_map.end()
356 }
357
358 pub fn deserialize<'de, D>(
360 deserializer: D,
361 ) -> Result<IdHashMap<T, S, A>, D::Error>
362 where
363 T: IdHashItem + Deserialize<'de> + fmt::Debug,
364 S: Default,
365 A: Clone + Default,
366 D: Deserializer<'de>,
367 {
368 deserializer.deserialize_map(MapVisitorAsMap {
369 _marker: PhantomData,
370 hasher: S::default(),
371 alloc: A::default(),
372 })
373 }
374}