statsig_rust/evaluation/
dynamic_string.rs

1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2use serde_json::Value;
3
4use crate::{hashing::ahash_str, interned_string::InternedString};
5
6#[derive(Clone, Eq, Debug)]
7pub struct DynamicString {
8    pub value: InternedString,
9    pub lowercased_value: InternedString,
10    pub hash_value: u64,
11}
12
13// ------------------------------------------------------------------------------- [Serialization]
14
15impl Serialize for DynamicString {
16    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17    where
18        S: Serializer,
19    {
20        if let Ok(bool_value) = self.value.parse::<bool>() {
21            return serializer.serialize_bool(bool_value);
22        }
23
24        serializer.serialize_str(&self.value)
25    }
26}
27
28impl<'de> Deserialize<'de> for DynamicString {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: Deserializer<'de>,
32    {
33        let value = String::deserialize(deserializer)?;
34        Ok(DynamicString::from(value))
35    }
36}
37
38// ------------------------------------------------------------------------------- [PartialEq]
39
40impl PartialEq for DynamicString {
41    fn eq(&self, other: &Self) -> bool {
42        self.value == other.value
43    }
44}
45
46impl PartialEq<&str> for DynamicString {
47    fn eq(&self, other: &&str) -> bool {
48        self.value.as_str() == *other
49    }
50}
51
52impl PartialEq<String> for DynamicString {
53    fn eq(&self, other: &String) -> bool {
54        self.value == *other
55    }
56}
57
58impl PartialEq<&String> for DynamicString {
59    fn eq(&self, other: &&String) -> bool {
60        self.value.as_str() == other.as_str()
61    }
62}
63
64// ------------------------------------------------------------------------------- [From<T> Implementations]
65
66impl From<Value> for DynamicString {
67    fn from(value: Value) -> Self {
68        let str_value = match value.as_str() {
69            Some(value) => value.to_string(),
70            None => value.to_string(),
71        };
72        DynamicString::from(str_value)
73    }
74}
75
76impl From<String> for DynamicString {
77    fn from(value: String) -> Self {
78        let hash_value = ahash_str(&value);
79        let lowercased_value = value.to_lowercase();
80
81        Self {
82            value: InternedString::from_string(value),
83            lowercased_value: InternedString::from_string(lowercased_value),
84            hash_value,
85        }
86    }
87}