capability_grower_configuration_comparison/
compare_capstone.rs1crate::ix!();
3
4pub trait CompareCapstone {
5 fn compare_capstone(&self, other: &GrowerTreeConfiguration) -> CompareOutcome;
6}
7
8impl CompareCapstone for GrowerTreeConfiguration {
9 fn compare_capstone(&self, other: &GrowerTreeConfiguration) -> CompareOutcome {
10 match (self.capstone(), other.capstone()) {
11 (None, None) => CompareOutcome::Exact,
12 (None, Some(cfg)) => {
13 if *cfg.mode() == CapstoneMode::Off {
17 CompareOutcome::Exact
18 } else {
19 CompareOutcome::Incompatible
20 }
21 },
22 (Some(cfg), None) => {
23 if *cfg.mode() == CapstoneMode::Off {
24 CompareOutcome::Exact
25 } else {
26 CompareOutcome::Incompatible
27 }
28 },
29 (Some(a), Some(b)) => {
30 if a.mode() != b.mode() {
32 return CompareOutcome::Incompatible;
33 }
34 let diff = (a.probability() - b.probability()).abs();
35 if diff < 0.01 {
37 CompareOutcome::Exact
38 } else if diff <= 0.2 {
39 CompareOutcome::Partial(1.0 - diff)
40 } else {
41 CompareOutcome::Incompatible
42 }
43 }
44 }
45 }
46}
47
48#[cfg(test)]
49mod compare_capstone_tests {
50 use super::*;
51
52 #[traced_test]
53 fn none_none_exact() {
54 let a = GrowerTreeConfiguration::default();
55 let b = GrowerTreeConfiguration::default();
56 assert_eq!(a.compare_capstone(&b), CompareOutcome::Exact);
57 }
58
59 #[traced_test]
60 fn same_mode_prob_exact() {
61 let cap = CapstoneGenerationConfigurationBuilder::default()
62 .mode(CapstoneMode::Probabilistic)
63 .probability(0.3)
64 .build()
65 .unwrap();
66 let a = GrowerTreeConfiguration::default()
67 .to_builder().capstone(Some(cap.clone())).build().unwrap();
68 let b = a.clone();
69 assert_eq!(a.compare_capstone(&b), CompareOutcome::Exact);
70 }
71
72 #[traced_test]
73 fn same_mode_different_prob_partial() {
74 let cap_a = CapstoneGenerationConfigurationBuilder::default()
76 .mode(CapstoneMode::Probabilistic)
77 .probability(0.2)
78 .build()
79 .unwrap();
80 let cap_b = CapstoneGenerationConfigurationBuilder::default()
81 .mode(CapstoneMode::Probabilistic)
82 .probability(0.4)
83 .build()
84 .unwrap();
85
86 let a = GrowerTreeConfiguration::default()
87 .to_builder().capstone(Some(cap_a)).build().unwrap();
88 let b = a.to_builder().capstone(Some(cap_b)).build().unwrap();
89
90 let out = a.compare_capstone(&b);
91 match out {
92 CompareOutcome::Partial(_) => {},
93 other => panic!("expected partial, got {:?}", other),
94 }
95 }
96
97 #[traced_test]
98 fn off_vs_single_incompatible() {
99 let off = CapstoneGenerationConfigurationBuilder::default()
101 .mode(CapstoneMode::Off)
102 .probability(0.0)
103 .build()
104 .unwrap();
105
106 let single = CapstoneGenerationConfigurationBuilder::default()
107 .mode(CapstoneMode::Single)
108 .probability(0.0)
109 .build()
110 .unwrap();
111
112 let a = GrowerTreeConfiguration::default()
113 .to_builder().capstone(Some(off)).build().unwrap();
114 let b = a.to_builder().capstone(Some(single)).build().unwrap();
115
116 let outcome = a.compare_capstone(&b);
117 assert_eq!(outcome, CompareOutcome::Incompatible, "Off vs Single => Incompatible");
118 }
119
120 #[traced_test]
121 fn one_none_one_probabilistic_incompatible() {
122 let prob = CapstoneGenerationConfigurationBuilder::default()
123 .mode(CapstoneMode::Probabilistic)
124 .probability(0.6)
125 .build()
126 .unwrap();
127 let a = GrowerTreeConfiguration::default();
128 let b = a.to_builder().capstone(Some(prob)).build().unwrap();
129 assert_eq!(a.compare_capstone(&b), CompareOutcome::Incompatible);
130 }
131}