rustriff_lib/domain/
tone_stack.rs1use atomic_float::AtomicF32;
2use std::sync::atomic::Ordering;
3use std::sync::Arc;
4use tracing::error;
5
6pub struct ToneStack {
14 bass: Arc<AtomicF32>,
15 middle: Arc<AtomicF32>,
16 treble: Arc<AtomicF32>,
17}
18
19impl ToneStack {
20 pub fn new() -> Self {
24 Self {
25 bass: Arc::new(AtomicF32::new(1.0)),
26 middle: Arc::new(AtomicF32::new(1.0)),
27 treble: Arc::new(AtomicF32::new(1.0)),
28 }
29 }
30
31 pub fn bass(&self) -> Arc<AtomicF32> {
35 Arc::clone(&self.bass)
36 }
37
38 pub fn middle(&self) -> Arc<AtomicF32> {
42 Arc::clone(&self.middle)
43 }
44
45 pub fn treble(&self) -> Arc<AtomicF32> {
49 Arc::clone(&self.treble)
50 }
51
52 pub fn set_bass(&self, bass: f32) {
64 if bass.is_sign_positive() && bass <= 1.0 {
65 self.bass.store(bass, Ordering::Relaxed);
66 } else {
67 error!("Bass must be a positive number between 0 and 1");
68 panic!("Bass must be positive and between 0 and 1");
69 }
70 }
71
72 pub fn set_middle(&self, middle: f32) {
84 if middle.is_sign_positive() && middle <= 1.0 {
85 self.middle.store(middle, Ordering::Relaxed);
86 } else {
87 error!("Middle must be a positive number between 0 and 1");
88 panic!("Middle must be positive and between 0 and 1");
89 }
90 }
91
92 pub fn set_treble(&self, treble: f32) {
104 if treble.is_sign_positive() && treble <= 1.0 {
105 self.treble.store(treble, Ordering::Relaxed);
106 } else {
107 error!("Treble must be a positive number between 0 and 1");
108 panic!("Treble must be positive and between 0 and 1");
109 }
110 }
111}
112
113impl Default for ToneStack {
114 fn default() -> Self {
115 Self::new()
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[cfg(test)]
124 mod success_path {
125 use super::*;
126
127 #[test]
128 fn bass_set_to_positive_value_within_range_should_succeed() {
129 let tone_stack = ToneStack::new();
130 tone_stack.set_bass(0.5);
131 assert_eq!(tone_stack.bass().load(Ordering::Relaxed), 0.5);
132 }
133 #[test]
134 fn middle_set_to_positive_value_within_range_should_succeed() {
135 let tone_stack = ToneStack::new();
136 tone_stack.set_middle(0.5);
137 assert_eq!(tone_stack.middle().load(Ordering::Relaxed), 0.5);
138 }
139 #[test]
140 fn treble_set_to_positive_value_within_range_should_succeed() {
141 let tone_stack = ToneStack::new();
142 tone_stack.set_treble(0.5);
143 assert_eq!(tone_stack.treble().load(Ordering::Relaxed), 0.5);
144 }
145 }
146
147 #[cfg(test)]
148 mod failure_path {
149 use super::*;
150
151 #[test]
152 #[should_panic(expected = "Bass must be positive and between 0 and 1")]
153 fn bass_set_to_negative_value_should_panic() {
154 let tone_stack = ToneStack::new();
155 tone_stack.set_bass(-0.5);
156 }
157 #[test]
158 #[should_panic(expected = "Bass must be positive and between 0 and 1")]
159 fn bass_set_to_value_greater_than_one_should_panic() {
160 let tone_stack = ToneStack::new();
161 tone_stack.set_bass(1.5);
162 }
163 #[test]
164 #[should_panic(expected = "Middle must be positive and between 0 and 1")]
165 fn middle_set_to_negative_value_should_panic() {
166 let tone_stack = ToneStack::new();
167 tone_stack.set_middle(-0.5);
168 }
169 #[test]
170 #[should_panic(expected = "Middle must be positive and between 0 and 1")]
171 fn middle_set_to_value_greater_than_one_should_panic() {
172 let tone_stack = ToneStack::new();
173 tone_stack.set_middle(1.5);
174 }
175 #[test]
176 #[should_panic(expected = "Treble must be positive and between 0 and 1")]
177 fn treble_set_to_negative_value_should_panic() {
178 let tone_stack = ToneStack::new();
179 tone_stack.set_treble(-0.5);
180 }
181 #[test]
182 #[should_panic(expected = "Treble must be positive and between 0 and 1")]
183 fn treble_set_to_value_greater_than_one_should_panic() {
184 let tone_stack = ToneStack::new();
185 tone_stack.set_treble(1.5);
186 }
187 }
188}