statsig_rust/
statsig_metadata.rs

1use crate::log_e;
2use lazy_static::lazy_static;
3use serde::Serialize;
4use serde_json::{json, Value};
5use std::collections::HashMap;
6use std::sync::RwLock;
7use uuid::Uuid;
8
9lazy_static! {
10    static ref STATSIG_METADATA: RwLock<StatsigMetadata> = RwLock::new(StatsigMetadata::new());
11}
12
13const TAG: &str = stringify!(StatsigMetadata);
14#[derive(Serialize, Clone)]
15#[serde(rename_all = "camelCase")]
16pub struct StatsigMetadata {
17    pub sdk_type: String,
18    pub sdk_version: String,
19
20    #[serde(rename = "sessionID")]
21    pub session_id: String,
22
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub os: Option<String>,
25
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub arch: Option<String>,
28
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub language_version: Option<String>,
31
32    #[serde(skip_serializing_if = "Option::is_none")]
33    #[serde(rename = "service_name")]
34    pub service_name: Option<String>,
35}
36
37impl StatsigMetadata {
38    fn new() -> Self {
39        Self {
40            sdk_version: "0.1.0".to_string(),
41            sdk_type: "statsig-server-core".to_string(),
42            session_id: Uuid::new_v4().to_string(),
43            os: None,
44            arch: None,
45            language_version: None,
46            service_name: None,
47        }
48    }
49
50    pub fn update_values(sdk_type: String, os: String, arch: String, language_version: String) {
51        match STATSIG_METADATA.write() {
52            Ok(mut metadata) => {
53                metadata.sdk_type = sdk_type;
54                metadata.os = Some(os);
55                metadata.arch = Some(arch);
56                metadata.language_version = Some(language_version);
57            }
58            Err(e) => {
59                log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
60            }
61        }
62    }
63
64    pub fn update_service_name(service_name: Option<String>) {
65        match STATSIG_METADATA.write() {
66            Ok(mut metadata) => {
67                metadata.service_name = service_name;
68            }
69            Err(e) => {
70                log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
71            }
72        }
73    }
74
75    #[must_use]
76    pub fn get_constant_request_headers(sdk_key: &str) -> HashMap<String, String> {
77        let meta = Self::get_metadata();
78
79        HashMap::from([
80            ("STATSIG-API-KEY".to_string(), sdk_key.to_string()),
81            ("STATSIG-SDK-TYPE".to_string(), meta.sdk_type),
82            ("STATSIG-SDK-VERSION".to_string(), meta.sdk_version),
83            ("STATSIG-SERVER-SESSION-ID".to_string(), meta.session_id),
84        ])
85    }
86
87    #[must_use]
88    pub fn get_metadata() -> StatsigMetadata {
89        match STATSIG_METADATA.read() {
90            Ok(metadata) => metadata.clone(),
91            Err(e) => {
92                log_e!(TAG, "Failed to clone StatsigMetadata: {}", e.to_string());
93                StatsigMetadata::new()
94            }
95        }
96    }
97
98    #[must_use]
99    pub fn get_as_json() -> Value {
100        json!(StatsigMetadata::get_metadata())
101    }
102}