1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
use std::collections::HashMap;
use crate::EvaluationError;
/// The result of evaluation.
pub type EvaluationResult<T> = Result<T, EvaluationError>;
// ============================================================
// EvaluationDetails
// ============================================================
/// The result of the flag evaluation process, and made available in the detailed flag resolution
/// functions.
#[derive(Clone, Default, Debug)]
pub struct EvaluationDetails<T> {
/// The flag key argument passed to the detailed flag evaluation method.
pub flag_key: String,
/// The value of evaluation result.
pub value: T,
/// The optional returned by the configured provider.
pub reason: Option<EvaluationReason>,
/// The optional variant returned by the configured provider.
pub variant: Option<String>,
/// The optional flag metadata returned by the configured provider.
/// If the provider returns nothing, it is set to the default value.
pub flag_metadata: FlagMetadata,
}
// ============================================================
// EvaluationReason
// ============================================================
/// Reason for evaluation.
#[derive(Clone, Default, Eq, PartialEq, Debug)]
pub enum EvaluationReason {
/// The resolved value is static (no dynamic evaluation).
Static,
/// The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or
/// dynamic evaluation yielded no result).
Default,
/// The resolved value was the result of a dynamic evaluation, such as a rule or specific
/// user-targeting.
TargetingMatch,
/// The resolved value was the result of pseudorandom assignment.
Split,
/// The resolved value was retrieved from cache.
Cached,
/// The resolved value was the result of the flag being disabled in the management system.
Disabled,
/// The reason for the resolved value could not be determined.
#[default]
Unknown,
/// The resolved value was the result of an error.
Error,
/// Other custom reason.
Other(String),
}
impl ToString for EvaluationReason {
fn to_string(&self) -> String {
match self {
Self::Static => "STATIC",
Self::Default => "DEFAULT",
Self::TargetingMatch => "TARGETING_MATCH",
Self::Split => "SPLIT",
Self::Cached => "CACHED",
Self::Disabled => "DISABLED",
Self::Unknown => "UNKNOWN",
Self::Error => "ERROR",
Self::Other(reason) => reason.as_str(),
}
.to_string()
}
}
// ============================================================
// FlagMetadata
// ============================================================
/// A structure which supports definition of arbitrary properties, with keys of type string, and
/// values of type boolean, string, or number.
///
/// This structure is populated by a provider for use by an Application Author (via the Evaluation
/// API) or an Application Integrator (via hooks).
#[derive(Clone, Default, PartialEq, Debug)]
pub struct FlagMetadata {
/// The fields of the metadata.
pub values: HashMap<String, FlagMetadataValue>,
}
impl FlagMetadata {
/// Append givne `key` and `value` to the fields of metadata.
#[must_use]
pub fn with_value(
mut self,
key: impl Into<String>,
value: impl Into<FlagMetadataValue>,
) -> Self {
self.add_value(key, value);
self
}
/// Append givne `key` and `value` to the fields of metadata.
pub fn add_value(&mut self, key: impl Into<String>, value: impl Into<FlagMetadataValue>) {
self.values.insert(key.into(), value.into());
}
}
// ============================================================
// FlagMetadataValue
// ============================================================
/// Supported values of flag metadata fields.
#[derive(Clone, PartialEq, Debug)]
#[allow(missing_docs)]
pub enum FlagMetadataValue {
Bool(bool),
Int(i64),
Float(f64),
String(String),
}
impl From<bool> for FlagMetadataValue {
fn from(value: bool) -> Self {
Self::Bool(value)
}
}
impl From<i8> for FlagMetadataValue {
fn from(value: i8) -> Self {
Self::Int(value.into())
}
}
impl From<i16> for FlagMetadataValue {
fn from(value: i16) -> Self {
Self::Int(value.into())
}
}
impl From<i32> for FlagMetadataValue {
fn from(value: i32) -> Self {
Self::Int(value.into())
}
}
impl From<i64> for FlagMetadataValue {
fn from(value: i64) -> Self {
Self::Int(value)
}
}
impl From<u8> for FlagMetadataValue {
fn from(value: u8) -> Self {
Self::Int(value.into())
}
}
impl From<u16> for FlagMetadataValue {
fn from(value: u16) -> Self {
Self::Int(value.into())
}
}
impl From<u32> for FlagMetadataValue {
fn from(value: u32) -> Self {
Self::Int(value.into())
}
}
impl From<f32> for FlagMetadataValue {
fn from(value: f32) -> Self {
Self::Float(value.into())
}
}
impl From<f64> for FlagMetadataValue {
fn from(value: f64) -> Self {
Self::Float(value)
}
}
impl From<String> for FlagMetadataValue {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<&str> for FlagMetadataValue {
fn from(value: &str) -> Self {
Self::String(value.into())
}
}