facade_protocol/
lib.rs

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/// Like `Layout`, but has physical appearance
59#[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/// Like `Container`, but without physical appearance (row, column, center)
79#[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);