1use crate::{
2 BiHashItem, BiHashMap, DefaultHashBuilder,
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: BiHashItem, S: Clone + BuildHasher, A: Allocator> Serialize
76 for BiHashMap<T, S, A>
77where
78 T: Serialize,
79{
80 fn serialize<Ser: Serializer>(
81 &self,
82 serializer: Ser,
83 ) -> Result<Ser::Ok, Ser::Error> {
84 self.items.serialize(serializer)
87 }
88}
89
90impl<
100 'de,
101 T: BiHashItem + fmt::Debug,
102 S: Clone + BuildHasher + Default,
103 A: Default + Allocator + Clone,
104> Deserialize<'de> for BiHashMap<T, S, A>
105where
106 T: Deserialize<'de>,
107{
108 fn deserialize<D: Deserializer<'de>>(
109 deserializer: D,
110 ) -> Result<Self, D::Error> {
111 deserializer.deserialize_any(SeqVisitor {
112 _marker: PhantomData,
113 hasher: S::default(),
114 alloc: A::default(),
115 })
116 }
117}
118
119impl<
120 'de,
121 T: BiHashItem + fmt::Debug + Deserialize<'de>,
122 S: Clone + BuildHasher,
123 A: Clone + Allocator,
124> BiHashMap<T, S, A>
125{
126 pub fn deserialize_in<D: Deserializer<'de>>(
129 deserializer: D,
130 alloc: A,
131 ) -> Result<Self, D::Error>
132 where
133 S: Default,
134 {
135 deserializer.deserialize_any(SeqVisitor {
136 _marker: PhantomData,
137 hasher: S::default(),
138 alloc,
139 })
140 }
141
142 pub fn deserialize_with_hasher<D: Deserializer<'de>>(
145 deserializer: D,
146 hasher: S,
147 ) -> Result<Self, D::Error>
148 where
149 A: Default,
150 {
151 deserializer.deserialize_any(SeqVisitor {
152 _marker: PhantomData,
153 hasher,
154 alloc: A::default(),
155 })
156 }
157
158 pub fn deserialize_with_hasher_in<D: Deserializer<'de>>(
161 deserializer: D,
162 hasher: S,
163 alloc: A,
164 ) -> Result<Self, D::Error> {
165 deserializer.deserialize_any(SeqVisitor {
166 _marker: PhantomData,
167 hasher,
168 alloc,
169 })
170 }
171}
172
173struct SeqVisitor<T, S, A> {
174 _marker: PhantomData<fn() -> T>,
175 hasher: S,
176 alloc: A,
177}
178
179impl<'de, T, S, A> Visitor<'de> for SeqVisitor<T, S, A>
180where
181 T: BiHashItem + Deserialize<'de> + fmt::Debug,
182 S: Clone + BuildHasher,
183 A: Clone + Allocator,
184{
185 type Value = BiHashMap<T, S, A>;
186
187 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
188 formatter
189 .write_str("a sequence or map of items representing a BiHashMap")
190 }
191
192 fn visit_seq<Access>(
193 self,
194 mut seq: Access,
195 ) -> Result<Self::Value, Access::Error>
196 where
197 Access: SeqAccess<'de>,
198 {
199 let mut map = BiHashMap::with_capacity_and_hasher_in(
200 cautious::<T>(seq.size_hint()),
201 self.hasher,
202 self.alloc,
203 );
204
205 while let Some(element) = seq.next_element()? {
206 map.insert_unique(element)
207 .map_err(serde_core::de::Error::custom)?;
208 }
209
210 Ok(map)
211 }
212
213 fn visit_map<Access>(
214 self,
215 mut map_access: Access,
216 ) -> Result<Self::Value, Access::Error>
217 where
218 Access: MapAccess<'de>,
219 {
220 let mut map = BiHashMap::with_capacity_and_hasher_in(
221 cautious::<T>(map_access.size_hint()),
222 self.hasher,
223 self.alloc,
224 );
225
226 while let Some((_, value)) =
227 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
228 {
229 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
230 }
231
232 Ok(map)
233 }
234}
235
236pub struct BiHashMapAsMap<T, S = DefaultHashBuilder, A: Allocator = Global> {
283 #[expect(clippy::type_complexity)]
284 _marker: PhantomData<fn() -> (T, S, A)>,
285}
286
287struct MapVisitorAsMap<T, S, A> {
288 _marker: PhantomData<fn() -> T>,
289 hasher: S,
290 alloc: A,
291}
292
293impl<'de, T, S, A> Visitor<'de> for MapVisitorAsMap<T, S, A>
294where
295 T: BiHashItem + Deserialize<'de> + fmt::Debug,
296 S: Clone + BuildHasher,
297 A: Clone + Allocator,
298{
299 type Value = BiHashMap<T, S, A>;
300
301 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
302 formatter.write_str("a map with items representing a BiHashMap")
303 }
304
305 fn visit_map<Access>(
306 self,
307 mut map_access: Access,
308 ) -> Result<Self::Value, Access::Error>
309 where
310 Access: MapAccess<'de>,
311 {
312 let mut map = BiHashMap::with_capacity_and_hasher_in(
313 cautious::<T>(map_access.size_hint()),
314 self.hasher,
315 self.alloc,
316 );
317
318 while let Some((_, value)) =
319 map_access.next_entry::<serde_core::de::IgnoredAny, T>()?
320 {
321 map.insert_unique(value).map_err(serde_core::de::Error::custom)?;
322 }
323
324 Ok(map)
325 }
326}
327
328impl<T, S, A> BiHashMapAsMap<T, S, A>
329where
330 S: Clone + BuildHasher,
331 A: Allocator,
332{
333 pub fn serialize<'a, Ser>(
335 map: &'a BiHashMap<T, S, A>,
336 serializer: Ser,
337 ) -> Result<Ser::Ok, Ser::Error>
338 where
339 T: BiHashItem + Serialize,
340 T: 'a,
341 T::K1<'a>: Serialize,
342 Ser: Serializer,
343 {
344 let mut ser_map = serializer.serialize_map(Some(map.len()))?;
345 for item in map.iter() {
346 let key1: T::K1<'a> = item.key1();
349 ser_map.serialize_entry(&key1, item)?;
350 }
351 ser_map.end()
352 }
353
354 pub fn deserialize<'de, D>(
356 deserializer: D,
357 ) -> Result<BiHashMap<T, S, A>, D::Error>
358 where
359 T: BiHashItem + Deserialize<'de> + fmt::Debug,
360 S: Default,
361 A: Clone + Default,
362 D: Deserializer<'de>,
363 {
364 deserializer.deserialize_map(MapVisitorAsMap {
365 _marker: PhantomData,
366 hasher: S::default(),
367 alloc: A::default(),
368 })
369 }
370}