statsig_rust/evaluation/
evaluation_types.rs1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5fn is_false(v: &bool) -> bool {
6 !(*v)
7}
8
9#[derive(Serialize, Deserialize, Clone, Debug)]
10#[serde(rename_all = "camelCase")]
11pub struct SecondaryExposure {
12 pub gate: String,
13 pub gate_value: String,
14 #[serde(rename = "ruleID")]
15 pub rule_id: String,
16}
17#[derive(Serialize, Deserialize, Clone)]
18pub struct BaseEvaluation {
19 pub name: String,
20 pub rule_id: String,
21 pub secondary_exposures: Vec<SecondaryExposure>,
22 #[serde(skip_serializing)]
23 pub sampling_rate: Option<u64>,
24 #[serde(skip_serializing)]
25 pub forward_all_exposures: Option<bool>,
26}
27
28pub enum AnyEvaluation<'a> {
29 FeatureGate(&'a GateEvaluation),
30 DynamicConfig(&'a DynamicConfigEvaluation),
31 Experiment(&'a ExperimentEvaluation),
32 Layer(&'a LayerEvaluation),
33}
34
35impl AnyEvaluation<'_> {
36 pub fn get_base_result(&self) -> &BaseEvaluation {
37 match self {
38 AnyEvaluation::FeatureGate(gate) => &gate.base,
39 AnyEvaluation::DynamicConfig(config) => &config.base,
40 AnyEvaluation::Experiment(experiment) => &experiment.base,
41 AnyEvaluation::Layer(layer) => &layer.base,
42 }
43 }
44
45 pub fn get_gate_bool_value(&self) -> bool {
46 match self {
47 AnyEvaluation::FeatureGate(eval) => eval.value,
48 _ => false, }
50 }
51}
52
53impl<'a> From<&'a LayerEvaluation> for AnyEvaluation<'a> {
54 fn from(layer_eval: &'a LayerEvaluation) -> Self {
55 AnyEvaluation::Layer(layer_eval)
56 }
57}
58
59impl<'a> From<&'a GateEvaluation> for AnyEvaluation<'a> {
60 fn from(gate_eval: &'a GateEvaluation) -> Self {
61 AnyEvaluation::FeatureGate(gate_eval)
62 }
63}
64
65impl<'a> From<&'a ExperimentEvaluation> for AnyEvaluation<'a> {
66 fn from(experiment_eval: &'a ExperimentEvaluation) -> Self {
67 AnyEvaluation::Experiment(experiment_eval)
68 }
69}
70
71impl<'a> From<&'a DynamicConfigEvaluation> for AnyEvaluation<'a> {
72 fn from(dynamic_config_evalation: &'a DynamicConfigEvaluation) -> Self {
73 AnyEvaluation::DynamicConfig(dynamic_config_evalation)
74 }
75}
76
77#[derive(Serialize, Deserialize, Clone)]
78pub struct GateEvaluation {
79 #[serde(flatten)]
80 pub base: BaseEvaluation,
81
82 pub id_type: String,
83 pub value: bool,
84}
85
86#[derive(Serialize, Deserialize, Clone)]
87pub struct DynamicConfigEvaluation {
88 #[serde(flatten)]
89 pub base: BaseEvaluation,
90
91 pub id_type: String,
92 pub value: HashMap<String, Value>,
93
94 pub group: String,
96 pub is_device_based: bool,
97
98 pub passed: bool,
99}
100
101#[derive(Serialize, Deserialize, Clone)]
102pub struct ExperimentEvaluation {
103 #[serde(flatten)]
104 pub base: BaseEvaluation,
105
106 pub id_type: String,
107 pub value: HashMap<String, Value>,
108
109 pub group: String,
111 pub is_device_based: bool,
112
113 #[serde(skip_serializing_if = "is_false")]
114 pub is_in_layer: bool,
115
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub explicit_parameters: Option<Vec<String>>,
118
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub group_name: Option<String>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub is_experiment_active: Option<bool>,
124
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub is_user_in_experiment: Option<bool>,
127}
128
129#[derive(Serialize, Deserialize, Clone)]
130#[serde(untagged)]
131pub enum AnyConfigEvaluation {
132 DynamicConfig(DynamicConfigEvaluation),
133 Experiment(ExperimentEvaluation),
134}
135
136#[derive(Serialize, Deserialize, Clone)]
137pub struct LayerEvaluation {
138 #[serde(flatten)]
139 pub base: BaseEvaluation,
140
141 pub value: HashMap<String, Value>,
142
143 pub group: String,
145 pub is_device_based: bool,
146
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub group_name: Option<String>,
149
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub is_experiment_active: Option<bool>,
152
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub is_user_in_experiment: Option<bool>,
155
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub allocated_experiment_name: Option<String>,
158 pub explicit_parameters: Vec<String>,
159 pub undelegated_secondary_exposures: Option<Vec<SecondaryExposure>>,
160}