Skip to main content

osom_lib_hash_tables/serde_impl/
abseil.rs

1use 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}