ferroui_dialogs/internal/
ferro_dialogs_internal_view_model_base.rs1use ferroui_base::data::model::{Event, INotifyPropertyChanged};
2use std::cell::{Cell, RefCell};
3
4#[derive(Default)]
12pub struct FerroDialogsInternalViewModelBase {
13 property_changed: Event<str>,
14}
15
16impl INotifyPropertyChanged for FerroDialogsInternalViewModelBase {
17 fn property_changed(&self) -> &Event<str> {
18 &self.property_changed
19 }
20}
21
22impl FerroDialogsInternalViewModelBase {
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn raise_and_set_if_changed<T: PartialEq>(&self, field: &RefCell<T>, value: T, property_name: &str) -> bool {
32 if *field.borrow() != value {
33 *field.borrow_mut() = value;
35 self.property_changed.raise(property_name);
36 return true;
37 }
38
39 false
40 }
41
42 pub fn raise_and_set_if_changed_cell<T: PartialEq + Copy>(&self, field: &Cell<T>, value: T, property_name: &str) -> bool {
44 if field.get() != value {
45 field.set(value);
46 self.property_changed.raise(property_name);
47 return true;
48 }
49
50 false
51 }
52
53 pub fn raise_property_changed(&self, property_name: &str) {
55 self.property_changed.raise(property_name);
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
63 use std::rc::Rc;
64
65 fn record(base: &FerroDialogsInternalViewModelBase) -> Rc<RefCell<Vec<String>>> {
66 let raised = Rc::new(RefCell::new(Vec::new()));
67 let sink = raised.clone();
68 base.property_changed().add(Rc::new(move |name: &str| sink.borrow_mut().push(name.to_string())));
69 raised
70 }
71
72 #[test]
73 fn raise_and_set_if_changed_stores_and_notifies_only_on_change() {
74 let base = FerroDialogsInternalViewModelBase::new();
75 let raised = record(&base);
76 let field = RefCell::new(String::from("a"));
77 let count = Cell::new(1);
78
79 assert!(!base.raise_and_set_if_changed(&field, String::from("a"), "Text"));
80 assert!(base.raise_and_set_if_changed(&field, String::from("b"), "Text"));
81 assert!(!base.raise_and_set_if_changed_cell(&count, 1, "Count"));
82 assert!(base.raise_and_set_if_changed_cell(&count, 2, "Count"));
83 base.raise_property_changed("Other");
84
85 assert_eq!("b", *field.borrow());
86 assert_eq!(2, count.get());
87 assert_eq!(vec!["Text", "Count", "Other"], *raised.borrow());
88 }
89}