statsig_rust/specs_response/
spec_directory.rs

1use std::sync::Arc;
2
3use ahash::HashMap;
4use serde::{Deserialize, Deserializer, Serialize};
5
6use super::spec_types::Spec;
7use crate::{hashing::ahash_str, interned_string::InternedString};
8
9#[derive(Debug, PartialEq)]
10pub struct AddressableSpec {
11    pub name: InternedString,
12    pub spec: Arc<Spec>,
13}
14
15#[derive(Debug, Default, PartialEq)]
16pub struct SpecDirectory {
17    pub specs: HashMap<u64, AddressableSpec>,
18}
19
20impl SpecDirectory {
21    pub fn get(&self, name: &str) -> Option<&AddressableSpec> {
22        let hash = ahash_str(name);
23        self.specs.get(&hash)
24    }
25
26    pub fn keys(&self) -> impl Iterator<Item = &str> {
27        self.specs.values().map(|v| v.name.as_str())
28    }
29
30    pub fn unperformant_keys(&self) -> Vec<String> {
31        self.specs
32            .values()
33            .map(|v| v.name.unperformant_to_string())
34            .collect()
35    }
36
37    pub fn unperformant_keys_entity_filter(&self, entity_type: &str) -> Vec<String> {
38        self.specs
39            .iter()
40            .filter(|(_, v)| v.spec.entity == entity_type)
41            .map(|(_, v)| v.name.unperformant_to_string())
42            .collect()
43    }
44}
45
46impl<'de> Deserialize<'de> for SpecDirectory {
47    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48    where
49        D: Deserializer<'de>,
50    {
51        let specs = HashMap::<String, Spec>::deserialize(deserializer)?
52            .into_iter()
53            .map(|(k, v)| {
54                let name = InternedString::from_str_ref(k.as_str());
55                let hash = name.hash;
56                let addressable = AddressableSpec {
57                    name,
58                    spec: Arc::new(v),
59                };
60
61                (hash, addressable)
62            })
63            .collect();
64
65        Ok(SpecDirectory { specs })
66    }
67}
68
69impl Serialize for SpecDirectory {
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where
72        S: serde::Serializer,
73    {
74        let map: HashMap<&str, &Spec> = self
75            .specs
76            .values()
77            .map(|v| (v.name.as_str(), v.spec.as_ref()))
78            .collect();
79
80        map.serialize(serializer)
81    }
82}