statsig_rust/specs_response/
specs_hash_map.rs

1use std::sync::Arc;
2
3use ahash::HashMap;
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5use serde_json::value::RawValue;
6
7use crate::{interned_string::InternedString, log_e, specs_response::spec_types::Spec};
8
9const TAG: &str = "SpecsHashMap";
10
11#[derive(PartialEq, Debug, Default)] /* DO_NOT_CLONE */
12pub struct SpecsHashMap(pub HashMap<InternedString, SpecPointer>);
13
14impl<'de> Deserialize<'de> for SpecsHashMap {
15    fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
16    where
17        D: Deserializer<'de>,
18    {
19        let raw_values: HashMap<InternedString, Box<RawValue>> =
20            Deserialize::deserialize(_deserializer)?;
21
22        let mut result = HashMap::default();
23        for (key, raw_value) in raw_values.into_iter() {
24            let json_string = raw_value.get();
25
26            let spec = match serde_json::from_str(json_string) {
27                Ok(spec) => spec,
28                Err(e) => {
29                    log_e!(TAG, "Failed to deserialize spec: {}", e);
30                    continue;
31                }
32            };
33
34            result.insert(
35                key,
36                SpecPointer {
37                    inner: Arc::new(spec),
38                },
39            );
40        }
41
42        Ok(SpecsHashMap(result))
43    }
44}
45
46impl Serialize for SpecsHashMap {
47    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
48    where
49        S: Serializer,
50    {
51        self.0.serialize(_serializer)
52    }
53}
54
55/// Feel free to add more HashMap pass-through methods here as needed.
56impl SpecsHashMap {
57    pub fn get(&self, key: &InternedString) -> Option<&SpecPointer> {
58        self.0.get(key)
59    }
60
61    pub fn keys(&self) -> impl Iterator<Item = &InternedString> {
62        self.0.keys()
63    }
64
65    pub fn iter(&self) -> impl Iterator<Item = (&InternedString, &SpecPointer)> {
66        self.0.iter()
67    }
68
69    pub fn insert(&mut self, key: InternedString, value: SpecPointer) {
70        self.0.insert(key, value);
71    }
72
73    pub fn len(&self) -> usize {
74        self.0.len()
75    }
76
77    pub fn is_empty(&self) -> bool {
78        self.0.is_empty()
79    }
80
81    pub fn clear(&mut self) {
82        self.0.clear();
83    }
84
85    pub fn remove(&mut self, key: &InternedString) -> Option<SpecPointer> {
86        self.0.remove(key)
87    }
88}
89
90#[derive(PartialEq, Debug, Clone /* Clone Ok because Arc */)]
91pub struct SpecPointer {
92    pub inner: Arc<Spec>,
93}
94
95impl Serialize for SpecPointer {
96    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
97    where
98        S: Serializer,
99    {
100        self.inner.serialize(serializer)
101    }
102}
103
104impl SpecPointer {
105    pub fn from_spec(spec: Spec) -> Self {
106        Self {
107            inner: Arc::new(spec),
108        }
109    }
110}