variant_map/btreemap/
lib.rs

1use serde::de::{DeserializeOwned, SeqAccess, Visitor};
2use serde::ser::SerializeSeq;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::collections::BTreeMap;
5use std::fmt::Formatter;
6use std::hash::Hash;
7use std::marker::PhantomData;
8use std::ops::{Deref, DerefMut, Index, IndexMut};
9
10use crate::common::MapValue;
11
12
13/// Trait to implement on your Enum [Keys][crate::common::MapValue::Key]
14/// Required to be a key of a [Map]
15pub trait OrdHashKey: Ord + Eq + Hash {}
16
17
18/// [Map] wrapping a [BTreeMap] used as associated [Map][crate::common::MapValue::Map]
19/// Keys must implement [OrdHashKey]
20#[derive(Debug, Clone)]
21pub struct Map<Key, Value>
22where
23    Key: OrdHashKey,
24{
25    inner: BTreeMap<Key, Value>,
26}
27
28impl<K, V> Map<K, V>
29where
30    K: OrdHashKey,
31{
32    pub fn insert(&mut self, value: V) -> Option<V>
33    where
34        K: OrdHashKey,
35        V: MapValue<Key = K>,
36    {
37        let key: K = value.to_key();
38        self.inner.insert(key, value)
39    }
40}
41
42impl<Key, Value> From<BTreeMap<Key, Value>> for Map<Key, Value>
43where
44    Key: OrdHashKey,
45{
46    fn from(value: BTreeMap<Key, Value>) -> Self {
47        Map::new(value)
48    }
49}
50
51impl<Key, Value> Map<Key, Value>
52where
53    Key: OrdHashKey,
54{
55    pub fn new(map: BTreeMap<Key, Value>) -> Self {
56        Map { inner: map }
57    }
58}
59
60impl<Key, Value> Default for Map<Key, Value>
61where
62    Key: OrdHashKey,
63{
64    fn default() -> Self {
65        Map {
66            inner: BTreeMap::new(),
67        }
68    }
69}
70
71impl<Key, Value> Serialize for Map<Key, Value>
72where
73    Key: OrdHashKey,
74    Value: Serialize,
75{
76    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77    where
78        S: Serializer,
79    {
80        let mut map = serializer.serialize_seq(Some(self.len()))?;
81
82        for v in self.deref().values() {
83            map.serialize_element(v)?
84        }
85
86        map.end()
87    }
88}
89
90struct MapVisitor<Key, Value>
91where
92    Key: OrdHashKey,
93{
94    marker: PhantomData<fn() -> Map<Key, Value>>,
95}
96
97impl<'de, Key, Value> Visitor<'de> for MapVisitor<Key, Value>
98where
99    Key: OrdHashKey,
100    Value: MapValue<Key = Key> + DeserializeOwned,
101{
102    type Value = Map<Key, Value>;
103
104    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
105        write!(formatter, "MapVisitor expects to receive a map of <EnumKey, Enum> with untagged Enum variants and EnumKey serializing to Enum variants' names ")
106    }
107
108    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
109    where
110        A: SeqAccess<'de>,
111    {
112        let mut map: BTreeMap<Key, Value> = BTreeMap::<Key, Value>::new();
113
114        while let Some(value) = seq.next_element()? {
115            let variant: Value = value;
116            map.insert(variant.to_key(), variant);
117        }
118
119        Ok(Map::from(map))
120    }
121}
122
123impl<'de, Key, Value> Deserialize<'de> for Map<Key, Value>
124where
125    Key: OrdHashKey,
126    Value: MapValue<Key = Key> + DeserializeOwned,
127{
128    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129    where
130        D: Deserializer<'de>,
131    {
132        let visitor = MapVisitor::<Key, Value> {
133            marker: PhantomData,
134        };
135        deserializer.deserialize_seq(visitor)
136    }
137}
138
139impl<Key, Value> Deref for Map<Key, Value>
140where
141    Key: OrdHashKey,
142{
143    type Target = BTreeMap<Key, Value>;
144
145    fn deref(&self) -> &Self::Target {
146        &self.inner
147    }
148}
149
150impl<Key, Value> DerefMut for Map<Key, Value>
151where
152    Key: OrdHashKey,
153{
154    fn deref_mut(&mut self) -> &mut Self::Target {
155        &mut self.inner
156    }
157}
158
159impl<Key, Value> Index<Key> for Map<Key, Value>
160where
161    Key: OrdHashKey,
162{
163    type Output = Value;
164
165    fn index(&self, index: Key) -> &Self::Output {
166        self.inner.get(&index).unwrap()
167    }
168}
169
170impl<Key, Value> IndexMut<Key> for Map<Key, Value>
171where
172    Key: OrdHashKey,
173{
174    fn index_mut(&mut self, index: Key) -> &mut Self::Output {
175        self.inner.get_mut(&index).unwrap()
176    }
177}
178
179impl<'a, Key, Value> IntoIterator for &'a Map<Key, Value>
180    where
181        Key: OrdHashKey {
182    type Item = <&'a BTreeMap<Key, Value> as IntoIterator>::Item;
183    type IntoIter = <&'a BTreeMap<Key, Value> as IntoIterator>::IntoIter;
184
185    fn into_iter(self) -> Self::IntoIter {
186        (&self.inner).into_iter()
187    }
188}
189
190impl<'a, Key, Value> IntoIterator for &'a mut Map<Key, Value>
191    where
192        Key: OrdHashKey {
193    type Item = <&'a mut BTreeMap<Key, Value> as IntoIterator>::Item;
194    type IntoIter = <&'a mut BTreeMap<Key, Value> as IntoIterator>::IntoIter;
195
196    fn into_iter(self) -> Self::IntoIter {
197        (&mut self.inner).into_iter()
198    }
199}