flipt 1.4.1

Flipt Server SDK
Documentation
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Default, Serialize)]
pub struct BatchEvaluationRequest {
    pub requests: Vec<EvaluationRequest>,
    pub reference: Option<String>,
}

#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EvaluationRequest {
    pub namespace_key: String,
    pub flag_key: String,
    pub entity_id: String,
    pub context: HashMap<String, String>,
    pub reference: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BooleanEvaluationResponse {
    pub enabled: bool,
    pub reason: EvaluationReason,
    #[serde(default)]
    pub segment_keys: Vec<String>,
    pub request_id: String,
    pub request_duration_millis: f64,
    pub timestamp: DateTime<Utc>,
    pub flag_key: String,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VariantEvaluationResponse {
    #[serde(rename = "match")]
    pub r#match: bool,
    pub segment_keys: Vec<String>,
    pub reason: EvaluationReason,
    pub variant_key: String,
    pub variant_attachment: String,
    pub request_id: String,
    pub request_duration_millis: f64,
    pub timestamp: DateTime<Utc>,
    pub flag_key: String,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ErrorEvaluationResponse {
    pub flag_key: String,
    pub namespace_key: String,
    pub reason: ErrorEvaluationReason,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BatchEvaluationResponse {
    pub request_id: String,
    pub responses: Vec<Response>,
    pub request_duration_millis: f64,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Response {
    pub r#type: EvaluationResponseType,
    pub boolean_response: Option<BooleanEvaluationResponse>,
    pub variant_response: Option<VariantEvaluationResponse>,
    pub error_response: Option<ErrorEvaluationResponse>,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub enum EvaluationReason {
    #[serde(rename = "UNKNOWN_EVALUATION_REASON")]
    Unknown,
    #[serde(rename = "FLAG_DISABLED_EVALUATION_REASON")]
    FlagDisabled,
    #[serde(rename = "MATCH_EVALUATION_REASON")]
    Match,
    #[serde(rename = "DEFAULT_EVALUATION_REASON")]
    Default,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub enum ErrorEvaluationReason {
    #[serde(rename = "UNKNOWN_ERROR_EVALUATION_REASON")]
    Unknown,
    #[serde(rename = "NOT_FOUND_ERROR_EVALUATION_REASON")]
    NotFound,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub enum EvaluationResponseType {
    #[serde(rename = "VARIANT_EVALUATION_RESPONSE_TYPE")]
    Variant,
    #[serde(rename = "BOOLEAN_EVALUATION_RESPONSE_TYPE")]
    Boolean,
    #[serde(rename = "ERROR_EVALUATION_RESPONSE_TYPE")]
    Error,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn boolean_evaluation_response_default_reason() {
        let json = r#"{
            "enabled":true,
            "reason":"DEFAULT_EVALUATION_REASON",
            "requestId":"fb502132-66e5-45a1-a315-f1a91d4f4637",
            "requestDurationMillis":3.070422,
            "timestamp":"2024-05-01T10:05:06.822847492Z",
            "flagKey":"flag_boolean"
        }"#;

        let response: BooleanEvaluationResponse = serde_json::from_str(json).unwrap();

        assert!(response.enabled);
        assert_eq!(response.reason, EvaluationReason::Default);
        assert_eq!(response.request_id, "fb502132-66e5-45a1-a315-f1a91d4f4637");
        assert_eq!(response.request_duration_millis, 3.070422);
        assert_eq!(
            response.timestamp,
            "2024-05-01T10:05:06.822847492Z"
                .parse::<DateTime<Utc>>()
                .unwrap()
        );
        assert_eq!(response.flag_key, "flag_boolean");
        assert!(response.segment_keys.is_empty());
    }
}