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,
},
}