use std::collections::BTreeSet;
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "op", rename_all = "snake_case", deny_unknown_fields)]
pub enum EditOperation {
CreateVariable {
id: String,
#[serde(rename = "type")]
variable_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
description: Option<String>,
default: JsonValue,
},
CreateCatalog {
id: String,
schema: JsonValue,
},
CreateEntry {
catalog: String,
key: String,
fields: JsonValue,
},
CreateList {
id: String,
#[serde(rename = "type")]
member_type: String,
members: Vec<JsonValue>,
#[serde(default, skip_serializing_if = "Option::is_none")]
description: Option<String>,
},
CreateContext {
id: String,
schema: JsonValue,
},
CreateLayer {
id: String,
unit: String,
buckets: i64,
},
CreateSample {
context: String,
key: String,
content: JsonValue,
},
Delete {
target: String,
},
SetDescription {
target: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
text: Option<String>,
},
SetType {
variable: String,
#[serde(rename = "type")]
variable_type: String,
},
SetDefault {
variable: String,
value: JsonValue,
},
AddRule {
variable: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
position: Option<usize>,
when: String,
value: JsonValue,
},
UpdateRule {
variable: String,
index: usize,
#[serde(default, skip_serializing_if = "Option::is_none")]
when: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
value: Option<JsonValue>,
},
RemoveRule {
variable: String,
index: usize,
},
MoveRule {
variable: String,
from: usize,
to: usize,
},
SetQuery {
variable: String,
from: String,
filter: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
sort: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
order: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
limit: Option<i64>,
},
ClearQuery {
variable: String,
},
SetField {
target: String,
value: JsonValue,
},
UnsetField {
target: String,
},
AddMember {
#[serde(rename = "list")]
list_id: String,
value: JsonValue,
},
RemoveMember {
#[serde(rename = "list")]
list_id: String,
value: JsonValue,
},
AddAllocation {
layer: String,
id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
status: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
eligibility: Option<String>,
arms: Vec<AllocationArmInput>,
},
RemoveAllocation {
layer: String,
id: String,
},
SetAllocationStatus {
layer: String,
id: String,
status: String,
},
SetAllocationEligibility {
layer: String,
id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
when: Option<String>,
},
SetArmBuckets {
layer: String,
allocation: String,
arm: String,
buckets: String,
},
ReplaceSample {
context: String,
key: String,
content: JsonValue,
},
}
impl EditOperation {
pub fn name(&self) -> &'static str {
match self {
Self::CreateVariable { .. } => "create_variable",
Self::CreateCatalog { .. } => "create_catalog",
Self::CreateEntry { .. } => "create_entry",
Self::CreateList { .. } => "create_list",
Self::CreateContext { .. } => "create_context",
Self::CreateLayer { .. } => "create_layer",
Self::CreateSample { .. } => "create_sample",
Self::Delete { .. } => "delete",
Self::SetDescription { .. } => "set_description",
Self::SetType { .. } => "set_type",
Self::SetDefault { .. } => "set_default",
Self::AddRule { .. } => "add_rule",
Self::UpdateRule { .. } => "update_rule",
Self::RemoveRule { .. } => "remove_rule",
Self::MoveRule { .. } => "move_rule",
Self::SetQuery { .. } => "set_query",
Self::ClearQuery { .. } => "clear_query",
Self::SetField { .. } => "set_field",
Self::UnsetField { .. } => "unset_field",
Self::AddMember { .. } => "add_member",
Self::RemoveMember { .. } => "remove_member",
Self::AddAllocation { .. } => "add_allocation",
Self::RemoveAllocation { .. } => "remove_allocation",
Self::SetAllocationStatus { .. } => "set_allocation_status",
Self::SetAllocationEligibility { .. } => "set_allocation_eligibility",
Self::SetArmBuckets { .. } => "set_arm_buckets",
Self::ReplaceSample { .. } => "replace_sample",
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AllocationArmInput {
pub name: String,
pub buckets: String,
}
#[derive(Clone, Debug, Default)]
pub struct EditOptions {
pub inherited: BTreeSet<String>,
}
#[derive(Clone, Debug, Serialize)]
pub struct EditOutcome {
pub plan: EditPlan,
pub records: Vec<ChangeRecord>,
}
#[derive(Clone, Debug, Default, Serialize)]
pub struct EditPlan {
pub writes: Vec<PlannedWrite>,
pub deletes: Vec<String>,
}
#[derive(Clone, Debug, Serialize)]
pub struct PlannedWrite {
pub path: String,
pub content: String,
}
#[derive(Clone, Debug, Serialize)]
pub struct ChangeRecord {
pub operation: &'static str,
pub address: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<JsonValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<JsonValue>,
}