pabitell_lib/
items.rs

1#[macro_export]
2macro_rules! simple_item {
3    ($class_name: ident, $name: literal, [$( $tag:expr ),* ]) => {
4        #[derive(Debug, Default)]
5        pub struct $class_name {
6            state: $crate::ItemState,
7            last_event: Option<usize>,
8        }
9
10        impl $crate::Named for $class_name {
11            fn name(&self) -> &'static str {
12                $name
13            }
14        }
15
16        impl $crate::Tagged for $class_name {
17            fn get_tags(&self) -> Vec<String> {
18                #[allow(unused_mut)]
19                let mut res: Vec<String> = vec![];
20                $(
21                    res.push($tag.into());
22                )*
23                res
24            }
25        }
26
27        impl $crate::Description for $class_name {}
28
29        impl $crate::AsAny for $class_name {
30            fn as_any(&self) -> &dyn Any {
31                self
32            }
33            fn as_any_mut(&mut self) -> &mut dyn Any {
34                self
35            }
36        }
37
38        impl $crate::Item for $class_name {
39            fn state(&self) -> &$crate::ItemState {
40                &self.state
41            }
42
43            fn set_state(&mut self, state: $crate::ItemState) {
44                self.state = state;
45            }
46
47            fn last_event(&self) -> Option<usize> {
48                self.last_event
49            }
50
51            fn set_last_event(&mut self, event: usize) {
52                self.last_event = Some(event);
53            }
54        }
55
56        impl $crate::Dumpable for $class_name {
57            fn dump(&self) -> serde_json::Value {
58                serde_json::json!(
59                    {
60                        "state": self.state.dump(),
61                        "name": self.name(),
62                        "last_event": self.last_event,
63                    }
64                )
65            }
66            fn load(&mut self, data: serde_json::Value) -> anyhow::Result<()> {
67                if let serde_json::Value::Object(mut object) = data {
68                    let state_json = object.remove("state").ok_or_else(|| anyhow::anyhow!("Wrong format of item '{}'", self.name()))?;
69                    let last_event_json = object.remove("last_event").ok_or_else(|| anyhow::anyhow!("Wrong format of item '{}'", self.name()))?;
70                    if let Some(last_event) = last_event_json.as_u64() {
71                        self.last_event = Some(last_event as usize);
72                    } else if last_event_json.is_null() {
73                        self.last_event = None;
74                    } else {
75                        return Err(anyhow::anyhow!("Wrong format of item '{}'", self.name()));
76                    }
77                    self.state.load(state_json)?;
78                    Ok(())
79                } else{
80                    Err(anyhow::anyhow!("Wrong format of item '{}'", self.name()))
81                }
82            }
83        }
84
85        impl $crate::Clean for $class_name {
86            fn clean(&mut self) {
87                self.state = $crate::ItemState::Unassigned;
88                self.last_event = None;
89            }
90        }
91
92    };
93}