Skip to main content

tibba_model/
schema.rs

1// Copyright 2025 Tree xie.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use serde::{Deserialize, Serialize, Serializer};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum Status {
19    Disabled = 0,
20    Enabled = 1,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum ResultValue {
25    Success = 0,
26    Failed = 1,
27}
28
29#[derive(Debug, Clone, Deserialize, Serialize, Default)]
30#[serde(rename_all = "snake_case")]
31pub enum SchemaType {
32    #[default]
33    String,
34    Number,
35    Bytes,
36    Boolean,
37    Status,
38    Result,
39    Strings,
40    Date,
41    ByteSize,
42    Json,
43    Code,
44    PopoverCard,
45    Placeholder,
46    Search,
47}
48
49#[derive(Debug, Clone, Deserialize)]
50pub enum SchemaOptionValue {
51    String(String),
52    Number(f64),
53    Integer(i64),
54}
55
56impl Serialize for SchemaOptionValue {
57    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58    where
59        S: Serializer,
60    {
61        match self {
62            SchemaOptionValue::String(s) => serializer.serialize_str(s),
63            SchemaOptionValue::Number(n) => serializer.serialize_f64(*n),
64            SchemaOptionValue::Integer(i) => serializer.serialize_i64(*i),
65        }
66    }
67}
68
69#[derive(Debug, Clone, Deserialize, Serialize)]
70pub struct SchemaOption {
71    pub label: String,
72    pub value: SchemaOptionValue,
73}
74
75pub(crate) fn new_schema_options(values: &[&str]) -> Vec<SchemaOption> {
76    values
77        .iter()
78        .map(|v| SchemaOption {
79            label: v.to_string(),
80            value: SchemaOptionValue::String(v.to_string()),
81        })
82        .collect()
83}
84
85#[derive(Debug, Clone, Deserialize, Serialize, Default)]
86#[serde(rename_all = "lowercase")]
87pub enum SchemaConditionType {
88    #[default]
89    Input,
90    Select,
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize, Default)]
94pub struct SchemaCondition {
95    pub name: String,
96    pub category: SchemaConditionType,
97    pub options: Option<Vec<SchemaOption>>,
98}
99
100#[derive(Debug, Clone, Deserialize, Serialize, Default)]
101pub struct SchemaAllowEdit {
102    pub owner: bool,
103    pub groups: Vec<String>,
104    pub roles: Vec<String>,
105    pub disabled: bool,
106}
107
108#[derive(Debug, Clone, Deserialize, Serialize, Default)]
109pub struct SchemaAllowCreate {
110    pub groups: Vec<String>,
111    pub roles: Vec<String>,
112    pub disabled: bool,
113}
114
115#[derive(Debug, Clone, Deserialize, Serialize, Default)]
116pub struct Schema {
117    pub name: String,
118    pub label: Option<String>,
119    pub category: SchemaType,
120    pub identity: bool,
121    pub read_only: bool,
122    pub auto_create: bool,
123    pub required: bool,
124    pub fixed: bool,
125    pub options: Option<Vec<SchemaOption>>,
126    pub hidden: bool,
127    pub popover: bool,
128    pub sortable: bool,
129    pub filterable: bool,
130    pub span: Option<u8>,
131    pub default_value: Option<serde_json::Value>,
132    pub hidden_values: Vec<String>,
133    pub max_width: Option<u16>,
134    pub combinations: Option<Vec<String>>,
135    pub search_model: Option<String>,
136}
137
138impl Schema {
139    pub fn new_id() -> Self {
140        Self {
141            name: "id".to_string(),
142            category: SchemaType::Number,
143            read_only: true,
144            required: true,
145            hidden: true,
146            auto_create: true,
147            ..Default::default()
148        }
149    }
150    pub fn new_status() -> Self {
151        Self {
152            name: "status".to_string(),
153            category: SchemaType::Status,
154            required: true,
155            default_value: Some(serde_json::json!(Status::Enabled as i8)),
156            ..Default::default()
157        }
158    }
159    pub fn new_remark() -> Self {
160        Self {
161            name: "remark".to_string(),
162            category: SchemaType::String,
163            required: true,
164            span: Some(2),
165            popover: true,
166            ..Default::default()
167        }
168    }
169    pub fn new_created() -> Self {
170        Self {
171            name: "created".to_string(),
172            category: SchemaType::Date,
173            read_only: true,
174            hidden: true,
175            auto_create: true,
176            ..Default::default()
177        }
178    }
179    pub fn new_modified() -> Self {
180        Self {
181            name: "modified".to_string(),
182            category: SchemaType::Date,
183            read_only: true,
184            sortable: true,
185            auto_create: true,
186            ..Default::default()
187        }
188    }
189    pub fn new_filterable_modified() -> Self {
190        let mut modified = Self::new_modified();
191        modified.filterable = true;
192        modified
193    }
194    pub fn new_user_search(name: impl Into<String>) -> Self {
195        Self {
196            name: name.into(),
197            category: SchemaType::Search,
198            search_model: Some("user".to_string()),
199            ..Default::default()
200        }
201    }
202    pub fn new_readonly_remark() -> Self {
203        Self {
204            name: "remark".to_string(),
205            category: SchemaType::String,
206            read_only: true,
207            popover: true,
208            ..Default::default()
209        }
210    }
211    pub fn new_name() -> Self {
212        Self {
213            name: "name".to_string(),
214            category: SchemaType::String,
215            required: true,
216            fixed: true,
217            ..Default::default()
218        }
219    }
220    pub fn new_effective_start_time() -> Self {
221        Self {
222            name: "effective_start_time".to_string(),
223            category: SchemaType::Date,
224            required: true,
225            ..Default::default()
226        }
227    }
228    pub fn new_effective_end_time() -> Self {
229        Self {
230            name: "effective_end_time".to_string(),
231            category: SchemaType::Date,
232            required: true,
233            ..Default::default()
234        }
235    }
236}
237
238#[derive(Debug, Clone, Deserialize, Serialize, Default)]
239pub struct SchemaView {
240    pub schemas: Vec<Schema>,
241    pub allow_edit: SchemaAllowEdit,
242    pub allow_create: SchemaAllowCreate,
243}