floopy/types/
experiments.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Deserialize)]
5pub struct Experiment {
6 pub id: String,
8 pub name: String,
10 pub description: Option<String>,
12 pub status: String,
14 pub variant_a_routing_rule_id: String,
16 pub variant_b_routing_rule_id: String,
18 pub split_percentage: i32,
20 pub created_at: String,
22 pub rolled_back_at: Option<String>,
24}
25
26#[derive(Debug, Clone, Deserialize)]
28pub struct ExperimentListPage {
29 pub items: Vec<Experiment>,
31 pub next_cursor: Option<String>,
33 pub has_more: bool,
35}
36
37#[derive(Debug, Clone, Deserialize)]
39pub struct VariantResults {
40 pub routing_rule_id: String,
42 pub sample_size: i64,
44 pub success_rate: f64,
46 pub average_latency_ms: f64,
48 pub average_cost_micro_usd: f64,
50}
51
52#[derive(Debug, Clone, Deserialize)]
54pub struct ExperimentResults {
55 pub experiment_id: String,
57 pub variant_a: VariantResults,
59 pub variant_b: VariantResults,
61 pub winner: Option<String>,
63 pub computed_at: String,
65}
66
67#[derive(Debug, Clone, Default)]
69pub struct ExperimentListParams {
70 pub status: Option<String>,
72 pub from: Option<String>,
74 pub to: Option<String>,
76 pub limit: Option<u32>,
78 pub cursor: Option<String>,
80}
81
82impl ExperimentListParams {
83 pub(crate) fn query(&self) -> Vec<(String, String)> {
84 let mut q = Vec::new();
85 if let Some(v) = &self.status {
86 q.push(("status".to_owned(), v.clone()));
87 }
88 if let Some(v) = &self.from {
89 q.push(("from".to_owned(), v.clone()));
90 }
91 if let Some(v) = &self.to {
92 q.push(("to".to_owned(), v.clone()));
93 }
94 if let Some(v) = self.limit {
95 q.push(("limit".to_owned(), v.to_string()));
96 }
97 if let Some(v) = &self.cursor {
98 q.push(("cursor".to_owned(), v.clone()));
99 }
100 q
101 }
102}
103
104#[derive(Debug, Clone, Serialize)]
106pub struct ExperimentCreateParams {
107 pub name: String,
109 pub variant_a_routing_rule_id: String,
111 pub variant_b_routing_rule_id: String,
113 #[serde(skip_serializing_if = "Option::is_none")]
115 pub description: Option<String>,
116 #[serde(skip_serializing_if = "Option::is_none")]
118 pub split_percentage: Option<i32>,
119}