balena_cdsl/output/
mod.rs

1//! A module containing output generator for the JSON Schema & UI Object
2use std::collections::HashMap;
3
4use serde_derive::Serialize;
5
6use crate::dsl::schema::Schema;
7use crate::dsl::schema::Widget;
8use crate::dsl::schema::KeysSchema;
9
10pub mod generator;
11mod serialization;
12
13/// JSON Schema wrapper
14pub struct JsonSchema<'a> {
15    schema_url: &'a str,
16    root: Schema,
17}
18
19/// It's different than UiObject as the root is nameless in the output
20#[derive(Clone, Debug, Serialize)]
21pub struct UiObjectRoot(Option<UiObjectProperty>);
22
23/// UI Object wrapper
24#[derive(Clone, Debug, Serialize)]
25pub struct UiObject(HashMap<String, UiObjectProperty>);
26
27#[derive(Clone, Debug, PartialEq, Serialize)]
28struct UiOptions {
29    removable: bool,
30    addable: bool,
31    orderable: bool,
32}
33
34#[derive(Clone, Debug, Serialize)]
35struct UiObjectProperty {
36    #[serde(rename = "ui:help", skip_serializing_if = "Option::is_none")]
37    help: Option<String>,
38    #[serde(rename = "ui:warning", skip_serializing_if = "Option::is_none")]
39    warning: Option<String>,
40    #[serde(rename = "ui:description", skip_serializing_if = "Option::is_none")]
41    description: Option<String>,
42    #[serde(rename = "ui:placeholder", skip_serializing_if = "Option::is_none")]
43    placeholder: Option<String>,
44    #[serde(rename = "ui:widget", skip_serializing_if = "Option::is_none")]
45    widget: Option<Widget>,
46    #[serde(flatten)]
47    properties: Option<UiObject>,
48    #[serde(flatten)]
49    keys: Option<KeysSchema>,
50    #[serde(rename = "ui:options", skip_serializing_if = "Option::is_none")]
51    ui_options: Option<UiOptions>,
52    #[serde(rename = "ui:readonly", skip_serializing_if = "Option::is_none")]
53    readonly: Option<bool>,
54    #[serde(rename = "ui:order", skip_serializing_if = "Option::is_none")]
55    order: Option<Vec<String>>,
56}
57
58impl UiObjectProperty {
59    /// Checks if an UI Object is empty
60    // FIXME: this is hard to maintain - need to remember to add things here
61    pub fn is_empty(&self) -> bool {
62        self.help.is_none()
63            && self.warning.is_none()
64            && self.description.is_none()
65            && self.widget.is_none()
66            && self.properties.is_none()
67            && self.keys.is_none()
68            && self.ui_options.is_none()
69            && self.placeholder.is_none()
70            && self.readonly.is_none()
71    }
72}
73
74impl UiObjectRoot {
75    pub fn is_empty(&self) -> bool {
76        match &self.0 {
77            None => true,
78            Some(property) => property.is_empty(),
79        }
80    }
81}
82
83impl UiObject {
84    pub fn is_empty(&self) -> bool {
85        self.0.is_empty()
86    }
87}
88
89impl Default for UiOptions {
90    fn default() -> Self {
91        UiOptions {
92            removable: true,
93            addable: true,
94            orderable: true,
95        }
96    }
97}