oxihuman_core/
param_set.rs1#![allow(dead_code)]
4
5use std::collections::HashMap;
6
7#[allow(dead_code)]
8#[derive(Debug, Clone)]
9pub enum ParamValue {
10 Float(f32),
11 Int(i64),
12 Bool(bool),
13 Text(String),
14}
15
16#[allow(dead_code)]
18pub struct ParamSet {
19 params: HashMap<String, ParamValue>,
20 dirty: bool,
21}
22
23#[allow(dead_code)]
24impl ParamSet {
25 pub fn new() -> Self {
26 Self {
27 params: HashMap::new(),
28 dirty: false,
29 }
30 }
31 pub fn set_float(&mut self, key: &str, v: f32) {
32 self.params.insert(key.to_string(), ParamValue::Float(v));
33 self.dirty = true;
34 }
35 pub fn set_int(&mut self, key: &str, v: i64) {
36 self.params.insert(key.to_string(), ParamValue::Int(v));
37 self.dirty = true;
38 }
39 pub fn set_bool(&mut self, key: &str, v: bool) {
40 self.params.insert(key.to_string(), ParamValue::Bool(v));
41 self.dirty = true;
42 }
43 pub fn set_text(&mut self, key: &str, v: &str) {
44 self.params
45 .insert(key.to_string(), ParamValue::Text(v.to_string()));
46 self.dirty = true;
47 }
48 pub fn get(&self, key: &str) -> Option<&ParamValue> {
49 self.params.get(key)
50 }
51 pub fn get_float(&self, key: &str) -> Option<f32> {
52 if let Some(ParamValue::Float(v)) = self.params.get(key) {
53 Some(*v)
54 } else {
55 None
56 }
57 }
58 pub fn get_int(&self, key: &str) -> Option<i64> {
59 if let Some(ParamValue::Int(v)) = self.params.get(key) {
60 Some(*v)
61 } else {
62 None
63 }
64 }
65 pub fn get_bool(&self, key: &str) -> Option<bool> {
66 if let Some(ParamValue::Bool(v)) = self.params.get(key) {
67 Some(*v)
68 } else {
69 None
70 }
71 }
72 pub fn get_text(&self, key: &str) -> Option<&str> {
73 if let Some(ParamValue::Text(v)) = self.params.get(key) {
74 Some(v.as_str())
75 } else {
76 None
77 }
78 }
79 pub fn remove(&mut self, key: &str) -> bool {
80 self.params.remove(key).is_some()
81 }
82 pub fn contains(&self, key: &str) -> bool {
83 self.params.contains_key(key)
84 }
85 pub fn len(&self) -> usize {
86 self.params.len()
87 }
88 pub fn is_empty(&self) -> bool {
89 self.params.is_empty()
90 }
91 pub fn is_dirty(&self) -> bool {
92 self.dirty
93 }
94 pub fn mark_clean(&mut self) {
95 self.dirty = false;
96 }
97 pub fn clear(&mut self) {
98 self.params.clear();
99 self.dirty = false;
100 }
101 pub fn keys(&self) -> Vec<&str> {
102 self.params.keys().map(|s| s.as_str()).collect()
103 }
104}
105
106impl Default for ParamSet {
107 fn default() -> Self {
108 Self::new()
109 }
110}
111
112#[allow(dead_code)]
113pub fn new_param_set() -> ParamSet {
114 ParamSet::new()
115}
116#[allow(dead_code)]
117pub fn ps_set_float(p: &mut ParamSet, k: &str, v: f32) {
118 p.set_float(k, v);
119}
120#[allow(dead_code)]
121pub fn ps_set_int(p: &mut ParamSet, k: &str, v: i64) {
122 p.set_int(k, v);
123}
124#[allow(dead_code)]
125pub fn ps_set_bool(p: &mut ParamSet, k: &str, v: bool) {
126 p.set_bool(k, v);
127}
128#[allow(dead_code)]
129pub fn ps_set_text(p: &mut ParamSet, k: &str, v: &str) {
130 p.set_text(k, v);
131}
132#[allow(dead_code)]
133pub fn ps_get_float(p: &ParamSet, k: &str) -> Option<f32> {
134 p.get_float(k)
135}
136#[allow(dead_code)]
137pub fn ps_get_int(p: &ParamSet, k: &str) -> Option<i64> {
138 p.get_int(k)
139}
140#[allow(dead_code)]
141pub fn ps_get_bool(p: &ParamSet, k: &str) -> Option<bool> {
142 p.get_bool(k)
143}
144#[allow(dead_code)]
145pub fn ps_get_text<'a>(p: &'a ParamSet, k: &str) -> Option<&'a str> {
146 p.get_text(k)
147}
148#[allow(dead_code)]
149pub fn ps_remove(p: &mut ParamSet, k: &str) -> bool {
150 p.remove(k)
151}
152#[allow(dead_code)]
153pub fn ps_contains(p: &ParamSet, k: &str) -> bool {
154 p.contains(k)
155}
156#[allow(dead_code)]
157pub fn ps_len(p: &ParamSet) -> usize {
158 p.len()
159}
160#[allow(dead_code)]
161pub fn ps_is_empty(p: &ParamSet) -> bool {
162 p.is_empty()
163}
164#[allow(dead_code)]
165pub fn ps_clear(p: &mut ParamSet) {
166 p.clear();
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172 #[test]
173 fn test_set_get_float() {
174 let mut p = new_param_set();
175 ps_set_float(&mut p, "speed", std::f32::consts::PI);
176 assert!(
177 (ps_get_float(&p, "speed").expect("should succeed") - std::f32::consts::PI).abs()
178 < 1e-6
179 );
180 }
181 #[test]
182 fn test_set_get_int() {
183 let mut p = new_param_set();
184 ps_set_int(&mut p, "count", 42);
185 assert_eq!(ps_get_int(&p, "count"), Some(42));
186 }
187 #[test]
188 fn test_set_get_bool() {
189 let mut p = new_param_set();
190 ps_set_bool(&mut p, "flag", true);
191 assert_eq!(ps_get_bool(&p, "flag"), Some(true));
192 }
193 #[test]
194 fn test_set_get_text() {
195 let mut p = new_param_set();
196 ps_set_text(&mut p, "name", "oxihuman");
197 assert_eq!(ps_get_text(&p, "name"), Some("oxihuman"));
198 }
199 #[test]
200 fn test_remove() {
201 let mut p = new_param_set();
202 ps_set_int(&mut p, "x", 1);
203 assert!(ps_remove(&mut p, "x"));
204 assert!(!ps_contains(&p, "x"));
205 }
206 #[test]
207 fn test_dirty_flag() {
208 let mut p = new_param_set();
209 ps_set_float(&mut p, "v", 1.0);
210 assert!(p.is_dirty());
211 p.mark_clean();
212 assert!(!p.is_dirty());
213 }
214 #[test]
215 fn test_len() {
216 let mut p = new_param_set();
217 assert_eq!(ps_len(&p), 0);
218 ps_set_int(&mut p, "a", 1);
219 assert_eq!(ps_len(&p), 1);
220 }
221 #[test]
222 fn test_clear() {
223 let mut p = new_param_set();
224 ps_set_bool(&mut p, "b", false);
225 ps_clear(&mut p);
226 assert!(ps_is_empty(&p));
227 }
228 #[test]
229 fn test_missing_key_returns_none() {
230 let p = new_param_set();
231 assert!(ps_get_float(&p, "nope").is_none());
232 }
233 #[test]
234 fn test_overwrite() {
235 let mut p = new_param_set();
236 ps_set_int(&mut p, "x", 1);
237 ps_set_int(&mut p, "x", 2);
238 assert_eq!(ps_get_int(&p, "x"), Some(2));
239 assert_eq!(ps_len(&p), 1);
240 }
241}