Skip to main content

statsig_rust/
data_store_interface.rs

1use std::fmt::Display;
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5
6use crate::{hashing::HashUtil, StatsigErr, StatsigOptions};
7
8pub enum RequestPath {
9    RulesetsV2,
10    RulesetsV1,
11    IDListsV1,
12    IDList,
13}
14
15impl Display for RequestPath {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        let value = match self {
18            RequestPath::IDListsV1 => "/v1/get_id_lists",
19            RequestPath::IDList => "id_list",
20            RequestPath::RulesetsV2 => "/v2/download_config_specs",
21            RequestPath::RulesetsV1 => "/v1/download_config_specs",
22        };
23        write!(f, "{value}")
24    }
25}
26
27pub enum CompressFormat {
28    PlainText,
29    Gzip,
30}
31
32impl Display for CompressFormat {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        let value = match self {
35            CompressFormat::PlainText => "plain_text",
36            CompressFormat::Gzip => "gzip",
37        };
38        write!(f, "{value}")
39    }
40}
41
42#[derive(Deserialize, Serialize)]
43pub struct DataStoreResponse {
44    pub result: Option<String>,
45    pub time: Option<u64>,
46}
47
48#[async_trait]
49pub trait DataStoreTrait: Send + Sync {
50    async fn initialize(&self) -> Result<(), StatsigErr>;
51    async fn shutdown(&self) -> Result<(), StatsigErr>;
52    async fn get(&self, key: &str) -> Result<DataStoreResponse, StatsigErr>;
53    async fn set(&self, key: &str, value: &str, time: Option<u64>) -> Result<(), StatsigErr>;
54    async fn support_polling_updates_for(&self, path: RequestPath) -> bool;
55}
56
57#[derive(Clone, Debug, Default)]
58pub enum DataStoreKeyVersion {
59    #[default]
60    V2Hashed,
61    V3HumanReadable,
62}
63
64impl From<&str> for DataStoreKeyVersion {
65    fn from(level: &str) -> Self {
66        match level.to_lowercase().as_str() {
67            "v2" | "2" => DataStoreKeyVersion::V2Hashed,
68            "v3" | "3" => DataStoreKeyVersion::V3HumanReadable,
69            _ => DataStoreKeyVersion::default(),
70        }
71    }
72}
73
74#[must_use]
75pub fn get_data_store_key(
76    path: RequestPath,
77    compress: CompressFormat,
78    sdk_key: &str,
79    hashing: &HashUtil,
80    options: &StatsigOptions,
81) -> String {
82    let key = match options
83        .data_store_key_schema_version
84        .clone()
85        .unwrap_or_default()
86    {
87        DataStoreKeyVersion::V3HumanReadable => {
88            let mut key = sdk_key.to_string();
89            key.truncate(20);
90            key
91        }
92        DataStoreKeyVersion::V2Hashed => hashing.hash(sdk_key, &crate::HashAlgorithm::Sha256),
93    };
94
95    format!("statsig|{path}|{compress}|{key}")
96}