zeph_experiments/
generator.rs1use std::collections::HashSet;
7
8use super::snapshot::ConfigSnapshot;
9use super::types::Variation;
10
11pub trait VariationGenerator: Send + Sync {
22 fn next(
27 &mut self,
28 baseline: &ConfigSnapshot,
29 visited: &HashSet<Variation>,
30 ) -> Option<Variation>;
31
32 fn name(&self) -> &'static str;
34}
35
36#[cfg(test)]
37mod tests {
38 use super::super::types::{ParameterKind, VariationValue};
39 use super::*;
40 use ordered_float::OrderedFloat;
41
42 struct AlwaysOne;
43
44 impl VariationGenerator for AlwaysOne {
45 fn next(
46 &mut self,
47 _baseline: &ConfigSnapshot,
48 visited: &HashSet<Variation>,
49 ) -> Option<Variation> {
50 let v = Variation {
51 parameter: ParameterKind::Temperature,
52 value: VariationValue::Float(OrderedFloat(1.0)),
53 };
54 if visited.contains(&v) { None } else { Some(v) }
55 }
56
57 fn name(&self) -> &'static str {
58 "always_one"
59 }
60 }
61
62 #[test]
63 fn generator_returns_variation_when_not_visited() {
64 let mut generator = AlwaysOne;
65 let baseline = ConfigSnapshot::default();
66 let visited = HashSet::new();
67 let v = generator.next(&baseline, &visited);
68 assert!(v.is_some());
69 assert_eq!(v.unwrap().parameter, ParameterKind::Temperature);
70 }
71
72 #[test]
73 fn generator_returns_none_when_visited() {
74 let mut generator = AlwaysOne;
75 let baseline = ConfigSnapshot::default();
76 let mut visited = HashSet::new();
77 visited.insert(Variation {
78 parameter: ParameterKind::Temperature,
79 value: VariationValue::Float(OrderedFloat(1.0)),
80 });
81 assert!(generator.next(&baseline, &visited).is_none());
82 }
83
84 #[test]
85 fn generator_name_is_static_str() {
86 let generator = AlwaysOne;
87 assert_eq!(generator.name(), "always_one");
88 }
89
90 #[test]
91 fn generator_is_send() {
92 fn assert_send<T: Send>() {}
93 assert_send::<AlwaysOne>();
94 }
95}