open_feature/evaluation/
details.rs1use std::collections::HashMap;
2use std::fmt::{Display, Formatter};
3
4use crate::EvaluationError;
5
6use super::Value;
7
8pub type EvaluationResult<T> = Result<T, EvaluationError>;
10
11#[derive(Clone, Default, Debug)]
18pub struct EvaluationDetails<T> {
19 pub flag_key: String,
21
22 pub value: T,
24
25 pub reason: Option<EvaluationReason>,
27
28 pub variant: Option<String>,
30
31 pub flag_metadata: FlagMetadata,
34}
35
36impl EvaluationDetails<Value> {
37 pub fn error_reason(flag_key: impl Into<String>, value: impl Into<Value>) -> Self {
39 Self {
40 value: value.into(),
41 flag_key: flag_key.into(),
42 reason: Some(EvaluationReason::Error),
43 variant: None,
44 flag_metadata: FlagMetadata::default(),
45 }
46 }
47}
48
49impl<T> EvaluationDetails<T>
50where
51 T: Into<Value>,
52{
53 pub fn into_value(self) -> EvaluationDetails<Value> {
55 EvaluationDetails {
56 flag_key: self.flag_key,
57 value: self.value.into(),
58 reason: self.reason,
59 variant: self.variant,
60 flag_metadata: self.flag_metadata,
61 }
62 }
63}
64
65#[derive(Clone, Default, Eq, PartialEq, Debug)]
71pub enum EvaluationReason {
72 Static,
74
75 Default,
78
79 TargetingMatch,
82
83 Split,
85
86 Cached,
88
89 Disabled,
91
92 #[default]
94 Unknown,
95
96 Error,
98
99 Other(String),
101}
102
103impl Display for EvaluationReason {
104 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
105 let reason = match self {
106 Self::Static => "STATIC",
107 Self::Default => "DEFAULT",
108 Self::TargetingMatch => "TARGETING_MATCH",
109 Self::Split => "SPLIT",
110 Self::Cached => "CACHED",
111 Self::Disabled => "DISABLED",
112 Self::Unknown => "UNKNOWN",
113 Self::Error => "ERROR",
114 Self::Other(reason) => reason.as_str(),
115 };
116 write!(f, "{reason}")
117 }
118}
119
120#[derive(Clone, Default, PartialEq, Debug)]
130pub struct FlagMetadata {
131 pub values: HashMap<String, FlagMetadataValue>,
133}
134
135impl FlagMetadata {
136 #[must_use]
138 pub fn with_value(
139 mut self,
140 key: impl Into<String>,
141 value: impl Into<FlagMetadataValue>,
142 ) -> Self {
143 self.add_value(key, value);
144 self
145 }
146
147 pub fn add_value(&mut self, key: impl Into<String>, value: impl Into<FlagMetadataValue>) {
149 self.values.insert(key.into(), value.into());
150 }
151}
152
153#[derive(Clone, PartialEq, Debug)]
159#[allow(missing_docs)]
160pub enum FlagMetadataValue {
161 Bool(bool),
162 Int(i64),
163 Float(f64),
164 String(String),
165}
166
167impl From<bool> for FlagMetadataValue {
168 fn from(value: bool) -> Self {
169 Self::Bool(value)
170 }
171}
172
173impl From<i8> for FlagMetadataValue {
174 fn from(value: i8) -> Self {
175 Self::Int(value.into())
176 }
177}
178
179impl From<i16> for FlagMetadataValue {
180 fn from(value: i16) -> Self {
181 Self::Int(value.into())
182 }
183}
184
185impl From<i32> for FlagMetadataValue {
186 fn from(value: i32) -> Self {
187 Self::Int(value.into())
188 }
189}
190
191impl From<i64> for FlagMetadataValue {
192 fn from(value: i64) -> Self {
193 Self::Int(value)
194 }
195}
196
197impl From<u8> for FlagMetadataValue {
198 fn from(value: u8) -> Self {
199 Self::Int(value.into())
200 }
201}
202
203impl From<u16> for FlagMetadataValue {
204 fn from(value: u16) -> Self {
205 Self::Int(value.into())
206 }
207}
208
209impl From<u32> for FlagMetadataValue {
210 fn from(value: u32) -> Self {
211 Self::Int(value.into())
212 }
213}
214
215impl From<f32> for FlagMetadataValue {
216 fn from(value: f32) -> Self {
217 Self::Float(value.into())
218 }
219}
220
221impl From<f64> for FlagMetadataValue {
222 fn from(value: f64) -> Self {
223 Self::Float(value)
224 }
225}
226
227impl From<String> for FlagMetadataValue {
228 fn from(value: String) -> Self {
229 Self::String(value)
230 }
231}
232
233impl From<&str> for FlagMetadataValue {
234 fn from(value: &str) -> Self {
235 Self::String(value.into())
236 }
237}