sorting_race/models/
config.rs1#[derive(Debug, Clone, PartialEq, Default)]
5pub enum Distribution {
6 #[default]
8 Shuffled,
9 NearlySorted,
11 Reversed,
13 FewUnique,
15 Sorted,
17 WithDuplicates,
19}
20
21#[derive(Debug, Clone, PartialEq)]
23pub enum FairnessMode {
24 ComparisonBudget { k: usize },
26 Weighted { alpha: f32, beta: f32 },
28 WallTime { slice_ms: u64 },
30 Adaptive { learning_rate: f32 },
32 EqualSteps,
34}
35
36impl Default for FairnessMode {
37 fn default() -> Self {
38 FairnessMode::ComparisonBudget { k: 10 }
39 }
40}
41
42#[derive(Debug, Clone)]
44pub struct RunConfiguration {
45 pub array_size: usize,
47 pub distribution: Distribution,
49 pub seed: u64,
51 pub fairness_mode: FairnessMode,
53 pub target_fps: u32,
55}
56
57impl Default for RunConfiguration {
58 fn default() -> Self {
59 Self {
60 array_size: 100,
61 distribution: Distribution::default(),
62 seed: 42,
63 fairness_mode: FairnessMode::default(),
64 target_fps: 30,
65 }
66 }
67}
68
69impl RunConfiguration {
70 pub fn new() -> Self {
72 Self::default()
73 }
74
75 pub fn with_array_size(mut self, size: usize) -> Self {
77 self.array_size = size;
78 self
79 }
80
81 pub fn with_distribution(mut self, distribution: Distribution) -> Self {
83 self.distribution = distribution;
84 self
85 }
86
87 pub fn with_seed(mut self, seed: u64) -> Self {
89 self.seed = seed;
90 self
91 }
92
93 pub fn with_fairness_mode(mut self, fairness_mode: FairnessMode) -> Self {
95 self.fairness_mode = fairness_mode;
96 self
97 }
98
99 pub fn with_target_fps(mut self, fps: u32) -> Self {
101 self.target_fps = fps;
102 self
103 }
104
105 pub fn validate(&self) -> Result<(), String> {
107 if self.array_size == 0 {
108 return Err("Array size must be greater than 0".to_string());
109 }
110
111 if self.target_fps == 0 {
112 return Err("Target FPS must be greater than 0".to_string());
113 }
114
115 match &self.fairness_mode {
116 FairnessMode::ComparisonBudget { k } => {
117 if *k == 0 {
118 return Err("Comparison budget must be greater than 0".to_string());
119 }
120 }
121 FairnessMode::WallTime { slice_ms } => {
122 if *slice_ms == 0 {
123 return Err("Wall time limit must be greater than 0".to_string());
124 }
125 }
126 FairnessMode::Weighted { alpha, beta } => {
127 if *alpha < 0.0 || *beta < 0.0 {
128 return Err("Weights must be non-negative".to_string());
129 }
130 }
131 FairnessMode::Adaptive { learning_rate } => {
132 if *learning_rate < 0.0 || *learning_rate > 1.0 {
133 return Err("Learning rate must be between 0.0 and 1.0".to_string());
134 }
135 }
136 FairnessMode::EqualSteps => {}
137 }
138
139 Ok(())
140 }
141}
142
143#[derive(Debug, Clone)]
145pub struct VisualConfiguration {
146 pub window_width: u32,
148 pub window_height: u32,
150 pub show_comparisons: bool,
152 pub show_names: bool,
154 pub show_metrics: bool,
156 pub animation_speed: f32,
158}
159
160impl Default for VisualConfiguration {
161 fn default() -> Self {
162 Self {
163 window_width: 800,
164 window_height: 600,
165 show_comparisons: true,
166 show_names: true,
167 show_metrics: true,
168 animation_speed: 1.0,
169 }
170 }
171}