statsig_rust/specs_response/
specs_hash_map.rs1use 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)] pub 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(key, SpecPointer::Pointer(Arc::new(spec)));
35 }
36
37 Ok(SpecsHashMap(result))
38 }
39}
40
41impl Serialize for SpecsHashMap {
42 fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
43 where
44 S: Serializer,
45 {
46 self.0.serialize(_serializer)
47 }
48}
49
50impl SpecsHashMap {
52 pub fn get(&self, key: &InternedString) -> Option<&SpecPointer> {
53 self.0.get(key)
54 }
55
56 pub fn keys(&self) -> impl Iterator<Item = &InternedString> {
57 self.0.keys()
58 }
59
60 pub fn iter(&self) -> impl Iterator<Item = (&InternedString, &SpecPointer)> {
61 self.0.iter()
62 }
63
64 pub fn insert(&mut self, key: InternedString, value: SpecPointer) {
65 self.0.insert(key, value);
66 }
67
68 pub fn len(&self) -> usize {
69 self.0.len()
70 }
71
72 pub fn is_empty(&self) -> bool {
73 self.0.is_empty()
74 }
75
76 pub fn clear(&mut self) {
77 self.0.clear();
78 }
79
80 pub fn remove(&mut self, key: &InternedString) -> Option<SpecPointer> {
81 self.0.remove(key)
82 }
83}
84
85#[derive(PartialEq, Debug, Clone )]
86pub enum SpecPointer {
87 Pointer(Arc<Spec>),
88 Static(&'static Spec),
89}
90
91impl SpecPointer {
92 pub fn as_spec_ref(&self) -> &Spec {
93 match self {
94 Self::Pointer(spec) => spec,
95 Self::Static(spec) => spec,
96 }
97 }
98}
99
100impl Serialize for SpecPointer {
101 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
102 where
103 S: Serializer,
104 {
105 match self {
106 Self::Pointer(spec) => spec.serialize(serializer),
107 Self::Static(spec) => spec.serialize(serializer),
108 }
109 }
110}
111
112impl SpecPointer {
113 pub fn from_spec(spec: Spec) -> Self {
114 Self::Pointer(Arc::new(spec))
115 }
116}