rs_sb3/
string_hashmap.rs

1//! Module to deal with Serde map
2
3use crate::prelude::*;
4use serde::de::MapAccess;
5use serde::ser::SerializeMap;
6use std::{collections::HashMap, fmt, marker::PhantomData};
7
8/// HashMap<String, V>
9#[derive(Debug, PartialEq, Clone, Eq)]
10pub struct StringHashMap<V>(pub HashMap<String, V>);
11
12impl<V> Default for StringHashMap<V> {
13    fn default() -> Self {
14        StringHashMap(HashMap::default())
15    }
16}
17
18// Serde impl ==================================================================
19
20struct StringHashMapVisitor<V> {
21    marker: PhantomData<fn() -> StringHashMap<V>>,
22}
23
24impl<V> StringHashMapVisitor<V> {
25    fn new() -> Self {
26        StringHashMapVisitor {
27            marker: PhantomData,
28        }
29    }
30}
31
32impl<'de, V> Visitor<'de> for StringHashMapVisitor<V>
33where
34    V: Deserialize<'de>,
35{
36    type Value = StringHashMap<V>;
37
38    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
39        formatter.write_str("string map")
40    }
41
42    fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
43    where
44        M: MapAccess<'de>,
45    {
46        let map = HashMap::with_capacity(access.size_hint().unwrap_or(0));
47        let mut map = StringHashMap(map);
48
49        while let Some((key, value)) = access.next_entry::<String, _>()? {
50            map.0.insert(key, value);
51        }
52
53        Ok(map)
54    }
55}
56
57impl<'de, V> Deserialize<'de> for StringHashMap<V>
58where
59    V: Deserialize<'de>,
60{
61    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
62    where
63        D: Deserializer<'de>,
64    {
65        deserializer.deserialize_map(StringHashMapVisitor::new())
66    }
67}
68
69impl<V: Serialize> Serialize for StringHashMap<V> {
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where
72        S: serde::Serializer,
73    {
74        let mut map_serializer = serializer.serialize_map(Some(self.0.len()))?;
75        for (k, v) in &self.0 {
76            map_serializer.serialize_entry(&k.to_string(), v)?;
77        }
78        map_serializer.end()
79    }
80}