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}