statsig_rust/evaluation/
evaluation_details.rs

1use crate::evaluation::evaluator_result::EvaluatorResult;
2use crate::spec_store::SpecStoreData;
3use crate::SpecsSource;
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
7pub struct EvaluationDetails {
8    pub reason: String,
9    pub lcut: Option<u64>,
10    pub received_at: Option<u64>,
11}
12
13impl EvaluationDetails {
14    pub fn unrecognized(spec_store_data: &SpecStoreData) -> Self {
15        Self::create_from_data(spec_store_data, "Unrecognized", &EvaluatorResult::default())
16    }
17
18    pub fn recognized_without_eval_result(spec_store_data: &SpecStoreData) -> Self {
19        Self::create_from_data(spec_store_data, "Recognized", &EvaluatorResult::default())
20    }
21
22    pub fn recognized(spec_store_data: &SpecStoreData, eval_result: &EvaluatorResult) -> Self {
23        Self::create_from_data(spec_store_data, "Recognized", eval_result)
24    }
25
26    pub fn recognized_but_overridden(
27        spec_store_data: &SpecStoreData,
28        override_reason: &str,
29    ) -> Self {
30        Self {
31            reason: format!("{override_reason}:Recognized"),
32            lcut: Some(spec_store_data.values.time),
33            received_at: spec_store_data.time_received_at,
34        }
35    }
36
37    #[must_use]
38    pub fn unrecognized_no_data() -> Self {
39        Self {
40            reason: SpecsSource::NoValues.to_string(),
41            lcut: None,
42            received_at: None,
43        }
44    }
45
46    #[must_use]
47    pub fn error(sub_reason: &str) -> Self {
48        Self {
49            reason: format!("Error:{sub_reason}"),
50            lcut: None,
51            received_at: None,
52        }
53    }
54
55    fn create_from_data(
56        data: &SpecStoreData,
57        sub_reason: &str,
58        eval_result: &EvaluatorResult,
59    ) -> Self {
60        if data.source == SpecsSource::Uninitialized || data.source == SpecsSource::NoValues {
61            return Self {
62                reason: data.source.to_string(),
63                lcut: None,
64                received_at: None,
65            };
66        }
67
68        if eval_result.unsupported {
69            return Self {
70                reason: format!("{}:Unsupported", data.source),
71                lcut: Some(data.values.time),
72                received_at: data.time_received_at,
73            };
74        }
75
76        Self {
77            reason: format!("{}:{}", data.source, sub_reason),
78            lcut: Some(data.values.time),
79            received_at: data.time_received_at,
80        }
81    }
82}