1pub mod dashboard;
2
3use bigdecimal::BigDecimal;
4use serde_derive::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct Action {
9 id: Id,
10 kind: Kind,
11}
12
13#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub enum Kind {
15 Click,
16}
17
18#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub enum Reaction {
20 Scene(Scene),
21 Delta(Delta),
22}
23
24pub type OverlayId = Option<Id>;
25
26impl Reaction {
27 pub fn overlay_id(&self) -> OverlayId {
28 match self {
29 Reaction::Scene(_) => None,
30 Reaction::Delta(delta) => Some(delta.id.clone()),
31 }
32 }
33}
34
35#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
36pub enum Scene {
37 Spinner,
38 FullScreen(Layout),
39 Dashboard(dashboard::Dashboard),
40}
41
42#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct Footer {
44 pub copyright: Value,
45 pub menu: Menu,
46}
47
48#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub struct Menu {
50 pub items: Vec<MenuItem>,
51}
52
53#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct MenuItem {
55 pub caption: Value,
56}
57
58#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub enum Container {
61 Blank,
62 Tabs(Vec<Tab>),
63 Panel(Panel),
64}
65
66#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
67pub struct Panel {
68 pub title: Option<Value>,
69 pub body: Layout,
70}
71
72#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
73pub struct Tab {
74 title: Value,
75 body: Layout,
76}
77
78#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
80pub enum Layout {
81 Blank,
82 Welcome,
83 Bind(Bind),
84 Control(Control),
85 Row(Vec<Layout>),
86 Column(Vec<Layout>),
87 List(List),
88 Container(Box<Container>),
89}
90
91impl From<Bind> for Layout {
92 fn from(bind: Bind) -> Self {
93 Self::Bind(bind)
94 }
95}
96
97impl From<Control> for Layout {
98 fn from(control: Control) -> Self {
99 Self::Control(control)
100 }
101}
102
103impl From<Container> for Layout {
104 fn from(container: Container) -> Self {
105 Self::Container(Box::new(container))
106 }
107}
108
109#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
110pub struct List {
111 pub items: Vec<ListItem>,
112}
113
114#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
115pub struct ListItem {
116 pub title: Value,
117 pub description: Value,
118 pub bind: Bind,
119}
120
121#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
122pub enum Bind {
123 Dynamic(Id),
124 Fixed(Value),
125}
126
127#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
128pub enum Control {
129 Button(Id),
130}
131
132#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
133pub struct Delta {
134 pub id: Id,
135 pub value: Value,
136}
137
138impl From<(Id, Value)> for Delta {
139 fn from((id, value): (Id, Value)) -> Self {
140 Self { id, value }
141 }
142}
143
144#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
145pub struct Id(String);
146
147impl<T: AsRef<str>> From<T> for Id {
148 fn from(value: T) -> Self {
149 Id(value.as_ref().to_string())
150 }
151}
152
153impl Default for Id {
154 fn default() -> Self {
155 Id("<default>".into())
156 }
157}
158
159#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
160pub enum Value {
161 Nothing,
162 String(String),
163 Decimal(BigDecimal),
164}
165
166impl Default for Value {
167 fn default() -> Self {
168 Value::Nothing
169 }
170}
171
172impl fmt::Display for Value {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 match self {
175 Value::Nothing => write!(f, ""),
176 Value::String(value) => write!(f, "{}", value),
177 Value::Decimal(value) => write!(f, "{}", value),
178 }
179 }
180}
181
182macro_rules! value_convert {
183 (@declare $var:ident $type:ty) => {
184 impl From<$type> for Value {
185 fn from(value: $type) -> Self {
186 Value::$var(value.into())
187 }
188 }
189 };
190 ($var:ident : $($type:ty),*) => {
191 $( value_convert!(@declare $var $type); )+
192 };
193}
194
195value_convert!(Decimal: u8, i8, u16, i16, u32, i32, u64, i64, BigDecimal);
196
197value_convert!(String: &str);