statsig_rust/event_logging/
exposable_string.rs1use crate::{hashing::ahash_str, log_e};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use serde_json::value::{to_raw_value, RawValue};
4use std::{borrow::Cow, sync::Arc};
5
6lazy_static::lazy_static! {
7 pub static ref EMPTY_STRING: ExposableString = ExposableString::from_str_ref("");
8 pub static ref DEFAULT_RULE: ExposableString = ExposableString::from_str_ref("default");
9 pub static ref DISABLED_RULE: ExposableString = ExposableString::from_str_ref("disabled");
10}
11
12const TAG: &str = "ExposableString";
13
14#[derive(Debug, Clone)]
15pub struct ExposableString {
16 pub hash_value: u64,
17
18 raw_value: Arc<Box<RawValue>>,
20}
21
22impl ExposableString {
23 pub fn from_str_parts(parts: &[&str]) -> Self {
24 let mut value = String::new();
25 for v in parts {
26 value.push_str(v);
27 }
28
29 Self::from_str_ref(&value)
30 }
31
32 pub fn from_str_ref(value: &str) -> Self {
33 let hash_value = ahash_str(value);
34
35 let raw_value: Box<RawValue> = match to_raw_value(value) {
36 Ok(raw_value) => raw_value,
37 Err(e) => {
38 log_e!(
39 TAG,
40 "Failed to convert string to raw value: {}, {}",
41 e,
42 value
43 );
44 return EMPTY_STRING.clone();
45 }
46 };
47
48 Self {
49 raw_value: Arc::new(raw_value),
50 hash_value,
51 }
52 }
53
54 pub fn from_raw_value(raw_value: Box<RawValue>) -> Self {
55 let hash_value = ahash_str(str_from_raw_value(&raw_value));
56 Self {
57 raw_value: Arc::new(raw_value),
58 hash_value,
59 }
60 }
61
62 pub fn as_str(&self) -> &str {
63 str_from_raw_value(&self.raw_value)
64 }
65
66 pub fn unperformant_to_string(&self) -> String {
70 self.as_str().to_owned()
71 }
72}
73
74impl Default for ExposableString {
75 fn default() -> Self {
76 EMPTY_STRING.clone()
77 }
78}
79
80impl<'de> Deserialize<'de> for ExposableString {
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 let value = Cow::<'de, str>::deserialize(deserializer)?;
86 Ok(Self::from_str_ref(&value))
87 }
88}
89
90impl Serialize for ExposableString {
91 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92 where
93 S: Serializer,
94 {
95 self.raw_value.serialize(serializer)
96 }
97}
98
99impl PartialEq for ExposableString {
100 fn eq(&self, other: &Self) -> bool {
101 self.hash_value == other.hash_value
102 }
103}
104
105impl Eq for ExposableString {}
106
107fn str_from_raw_value(raw_value: &RawValue) -> &str {
108 let value = raw_value.get();
109 if value.len() >= 2 {
110 &value[1..value.len() - 1]
111 } else {
112 ""
113 }
114}