embedded_multi_page_hmi/setting.rs
1use std::fmt::Debug;
2use std::{cell::Cell, default::Default, str::FromStr};
3
4/// A setting can be set and get
5///
6/// A setting can be multiple borrowed since the update function does not require a
7/// &mut self mutating reference
8///
9/// # Example
10///
11/// ```
12/// use embedded_multi_page_hmi::{CellSetting, Setting};
13/// let setting: CellSetting<f32> = Default::default();
14/// let s1 = &setting;
15/// let s2 = &setting;
16/// assert_eq!(0.0f32, s1.get());
17/// assert_eq!(0.0f32, s2.get());
18/// s1.set(32.0);
19/// assert_eq!(32.0f32, s1.get());
20/// assert_eq!(32.0f32, s2.get());
21/// ```
22pub trait Setting {
23 type Item: Copy;
24
25 /// Set the value of the setting
26 ///
27 /// The set function does not require a `&mut self` parameter on purpose
28 fn set(&self, value: Self::Item);
29
30 /// Set the value of the setting obtained from string slice
31 ///
32 /// The set function does not require a `&mut self` parameter on purpose
33 fn set_string(&self, value: &str);
34
35 /// Get the value of the setting into a string slice
36 fn get(&self) -> Self::Item;
37
38 /// Check if a certain string represented setting value meets the type spec
39 /// of the setting.
40 ///
41 /// An example is a range check of the number, or check for a certain
42 /// regex pattern.
43 fn is_valid(&self, _value: &str) -> bool {
44 true
45 }
46}
47
48/// A setting implemented using Cell
49///
50/// The capability of a Cell is to allow interior mutability.
51/// This is exactly the behavior needed to implement a setting trat object
52/// for integers of float numbers.
53#[derive(Default)]
54pub struct CellSetting<T>(Cell<T>);
55
56impl<T: Copy + FromStr> Setting for CellSetting<T>
57where
58 <T as FromStr>::Err: Debug,
59{
60 type Item = T;
61
62 fn set(&self, value: Self::Item) {
63 self.0.set(value);
64 }
65
66 fn get(&self) -> Self::Item {
67 self.0.get()
68 }
69
70 fn set_string(&self, value: &str) {
71 let v = T::from_str(value).unwrap();
72 self.0.set(v);
73 }
74}