use core::fmt::Debug;
use std::fmt;
pub struct Setting<T> {
val: T,
cb: Box<dyn FnMut(&T, &T)>,
}
impl<T> Debug for Setting<T>
where
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.val)
}
}
impl<T> Setting<T>
where
T: Default + Clone,
{
fn new(f: impl FnMut(&T, &T) + 'static) -> Self {
Self {
val: T::default(),
cb: Box::new(f),
}
}
pub fn cb(&mut self, f: impl FnMut(&T, &T) + 'static) {
self.cb = Box::new(f);
}
pub fn set(&mut self, new_val: T) -> () {
(self.cb)(&self.val, &new_val);
self.val = new_val;
}
pub fn get(&self) -> T {
self.val.clone()
}
}
impl<T> Default for Setting<T>
where
T: Default + Debug + Clone,
{
fn default() -> Self {
Self::new(|_, _| {})
}
}
#[cfg(test)]
mod tests {
use crate::Setting;
use std::cell::{Cell, RefCell};
#[derive(Default, Debug)]
struct Settings {
num: Setting<u16>,
str: Setting<String>,
cell: Setting<Cell<u16>>,
refcell: Setting<RefCell<u8>>,
vec: Setting<Vec<u8>>,
}
#[test]
fn default_settings() {
let settings = Settings::default();
assert_eq!("", settings.str.get());
assert_eq!(0, settings.num.get());
}
#[test]
fn set_get_value_type() {
let mut settings = Settings::default();
settings.str.set("abc".to_string());
assert_eq!("abc", settings.str.get());
settings.num.set(8080);
assert_eq!(8080, settings.num.get());
}
#[test]
fn set_get_cell_type() {
let mut settings = Settings::default();
settings.cell.set(10.into());
assert_eq!(settings.cell.get(), 10.into());
}
#[test]
fn set_get_refcell_type() {
let mut settings = Settings::default();
settings.refcell.set(11.into());
assert_eq!(settings.refcell.get(), 11.into());
}
#[test]
fn set_get_vec_type() {
let mut settings = Settings::default();
let mut vec: Vec<u8> = settings.vec.get();
vec.push(10);
vec.push(20);
settings.vec.set(vec); assert_eq!(settings.vec.get().get(0).unwrap().to_owned(), 10);
assert_eq!(settings.vec.get().get(1).unwrap().to_owned(), 20);
}
}