hypertune 0.6.2

Hypertune SDK for type safe configuration
Documentation
use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use serde_json::Map;
use serde_json::Number;
use serde_json::Value;

use crate::expression::Logs;

pub type SplitMap = HashMap<String, Split>;

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Split {
    pub id: String,
    pub r#type: SplitType,
    pub dimensions: HashMap<String, Dimension>,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
pub enum SplitType {
    #[serde(rename = "test")]
    Test,

    #[serde(rename = "ml")]
    ML,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum Dimension {
    Discrete(DiscreteDimension),
    Continuous(ContinuousDimension),
}

impl Dimension {
    pub fn get_id(&self) -> &str {
        match self {
            Dimension::Discrete(d) => &d.id,
            Dimension::Continuous(d) => &d.id,
        }
    }
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DiscreteDimension {
    pub id: String,
    split_id: String,
    index: u64,
    name: String,
    pub arms: HashMap<String, Arm>,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ContinuousDimension {
    pub id: String,
    split_id: String,
    index: u64,
    name: String,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Arm {
    pub id: String,
    dimension_id: String,
    pub index: u64,
    name: String,
    pub allocation: Number,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CommitConfig {
    pub split_config: HashMap<String, SplitConfig>,
}

impl CommitConfig {
    pub fn new() -> Self {
        Self {
            split_config: HashMap::new(),
        }
    }
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(tag = "type")]
pub enum SplitConfig {
    EpsilonGreedyConfig(EpsilonGreedyConfig),
    PersonalizationSplitConfig(PersonalizationSplitConfig),
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct EpsilonGreedyConfig {
    pub epsilon: Number,
    pub best_assignment: HashMap<String, SplitAssignmentEntry>,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
pub struct PersonalizationSplitConfig {
    pub epsilon: Number,
    pub logic: HashMap<String, PersonalizationSplitLogicDimension>,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PersonalizationSplitLogicDimension {
    pub rules: Vec<PersonalSplitLogicDimensionRule>,
    pub default_arm_id: String,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PersonalSplitLogicDimensionRule {
    pub feature_values_path: Vec<String>,
    pub feature_value: Value,
    pub arm_id: String,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct AssignmentCacheValue {
    pub assignment: HashMap<String, SplitAssignmentEntry>,
    pub event_object_type_name: Option<String>,
    pub event_payload: Option<Map<String, Value>>,
    pub event_payload_logs: Option<Logs>,
}

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone, Hash)]
#[serde(rename_all = "camelCase")]
pub struct AssignmentCacheKey {
    pub split_id: String,
    pub unit_id: String,
}

pub type AssignmentCache = HashMap<AssignmentCacheKey, AssignmentCacheValue>;

#[derive(Deserialize, Serialize, Eq, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum SplitAssignmentEntry {
    #[serde(rename_all = "camelCase")]
    Discrete {
        arm_id: String,
    },

    Continuous {
        value: Number,
    },
}