osom_lib_hash_tables/serde_impl/
abseil.rs1use core::{hash::Hash, marker::PhantomData};
2
3use osom_lib_primitives::length::Length;
4use serde::{
5 Deserialize, Serialize,
6 de::{self, Visitor},
7 ser::SerializeMap,
8};
9
10use crate::{
11 abseil::{configuration::AbseilConfig, hash_table::AbseilHashTable},
12 traits::{ImmutableHashTable, MutableHashTable},
13};
14
15impl<TKey, TValue, TConfig> Serialize for AbseilHashTable<TKey, TValue, TConfig>
16where
17 TKey: Eq + Hash + Serialize,
18 TValue: Serialize,
19 TConfig: AbseilConfig,
20{
21 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: serde::Serializer,
24 {
25 let mut m = serializer.serialize_map(Some(self.length().as_usize()))?;
26 for kvp in self.iter() {
27 m.serialize_entry(&kvp.key, &kvp.value)?;
28 }
29 m.end()
30 }
31}
32
33struct AbseilVisitor<TKey, TValue, TConfig> {
34 _phantom: PhantomData<(TKey, TValue, TConfig)>,
35}
36
37impl<TKey, TValue, TConfig> AbseilVisitor<TKey, TValue, TConfig> {
38 #[inline(always)]
39 pub const fn new() -> Self {
40 Self { _phantom: PhantomData }
41 }
42}
43
44impl<'de, TKey, TValue, TConfig> Visitor<'de> for AbseilVisitor<TKey, TValue, TConfig>
45where
46 TKey: Eq + Hash + Deserialize<'de>,
47 TValue: Deserialize<'de>,
48 TConfig: AbseilConfig + Default,
49{
50 type Value = AbseilHashTable<TKey, TValue, TConfig>;
51
52 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
53 formatter.write_str("a (key, value) mapping")
54 }
55
56 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
57 where
58 A: serde::de::MapAccess<'de>,
59 {
60 let capacity = map.size_hint().unwrap_or(0);
61 let length = Length::try_from_usize(capacity).map_err(de::Error::custom)?;
62 let mut result = AbseilHashTable::<TKey, TValue, TConfig>::with_capacity(length).map_err(de::Error::custom)?;
63 while let Some((key, value)) = map.next_entry::<TKey, TValue>()? {
64 result.try_insert(key, value).map_err(de::Error::custom)?;
65 }
66 Ok(result)
67 }
68}
69
70impl<'de, TKey, TValue, TConfig> Deserialize<'de> for AbseilHashTable<TKey, TValue, TConfig>
71where
72 TKey: Eq + Hash + Deserialize<'de>,
73 TValue: Deserialize<'de>,
74 TConfig: AbseilConfig + Default,
75{
76 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77 where
78 D: serde::Deserializer<'de>,
79 {
80 deserializer.deserialize_map(AbseilVisitor::new())
81 }
82}