balena_cdsl/dsl/schema/
mod.rs1use std::collections::HashMap;
3
4use regex::Regex;
5use serde_derive::Deserialize;
6use serde_derive::Serialize;
7
8use crate::dsl::schema::object_types::ObjectType;
9
10pub mod deserialization;
11pub mod compiler;
12pub mod object_types;
13mod dynamic;
14
15#[derive(Clone, Debug)]
17pub struct DocumentRoot(Schema);
18
19#[derive(Clone, Debug)]
21pub struct SchemaList {
22 entries: Vec<NamedSchema>,
23}
24
25#[derive(Clone, Debug, Serialize)]
28pub struct NamedSchema {
29 pub name: String,
30 #[serde(flatten)]
31 pub schema: Schema,
32}
33
34#[derive(Clone, Debug)]
36pub struct Schema {
37 pub version: Option<u64>,
38 pub object_type: ObjectType,
39 pub annotations: Annotations,
40 pub children: Option<SchemaList>,
42 pub dynamic: Option<Box<KeysValues>>,
44 pub formula: Option<String>,
46}
47
48#[derive(Clone, Default, Debug, Deserialize)]
50pub struct Annotations {
51 pub title: Option<String>,
52 pub help: Option<String>,
53 pub warning: Option<String>,
54 pub description: Option<String>,
55 pub placeholder: Option<String>,
56 pub widget: Option<Widget>,
57 pub orderable: Option<bool>,
58 pub addable: Option<bool>,
59 pub removable: Option<bool>,
60 pub hidden: Option<bool>,
61 #[serde(rename = "readOnly")]
62 pub readonly: Option<bool>,
63 #[serde(rename = "writeOnly")]
64 pub writeonly: Option<bool>,
65}
66
67#[derive(Clone, Debug, Serialize, Deserialize)]
68#[serde(rename_all = "lowercase")]
69pub enum Widget {
70 Textarea,
71 Hidden,
72 Password,
73}
74
75#[derive(Clone, Debug)]
76pub struct KeysSchema {
77 pub pattern: Regex,
78 pub title: Option<String>,
79}
80
81#[derive(Clone, Debug)]
82pub struct KeysValues {
83 pub keys: KeysSchema,
84 pub values: Schema,
85}
86
87impl NamedSchema {
88 pub fn unpack(&self) -> (&str, &Schema) {
90 (self.name.as_ref(), &self.schema)
91 }
92}
93
94impl Schema {
95 pub fn with_version(self, version: u64) -> Schema {
96 Schema {
97 version: Some(version),
98 ..self
99 }
100 }
101}
102
103impl DocumentRoot {
104 pub fn schema(self) -> Schema {
105 self.0
106 }
107}
108
109impl SchemaList {
111 pub fn is_empty(&self) -> bool {
112 self.entries.is_empty()
113 }
114
115 pub fn all_as_map(&self) -> HashMap<&str, &Schema> {
117 self.entries().iter().map(|schema| schema.unpack()).collect()
118 }
119
120 pub fn all_names(&self) -> Vec<&str> {
121 self.entries().iter().map(|schema| schema.name.as_str()).collect()
122 }
123
124 pub fn entries(&self) -> &Vec<NamedSchema> {
125 &self.entries
126 }
127
128 pub fn required_schema_names(&self) -> Vec<&str> {
129 self.entries
130 .iter()
131 .filter_map(|named_schema| {
132 let object_type = &named_schema.schema.object_type;
133 match object_type {
134 ObjectType::Required(_) => Some(named_schema.name.as_str()),
135 ObjectType::Optional(_) => None,
136 }
137 })
138 .collect()
139 }
140}
141
142impl Annotations {
143 pub fn with_title_option(title: Option<String>) -> Annotations {
144 let default = Annotations::default();
145 Annotations { title, ..default }
146 }
147}