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 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)]
86pub struct SchemaAllowEdit {
87    pub owner: bool,
88    pub groups: Vec<String>,
89    pub roles: Vec<String>,
90    pub disabled: bool,
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize, Default)]
94pub struct SchemaAllowCreate {
95    pub groups: Vec<String>,
96    pub roles: Vec<String>,
97    pub disabled: bool,
98}
99
100#[derive(Debug, Clone, Deserialize, Serialize, Default)]
101pub struct Schema {
102    pub name: String,
103    pub label: Option<String>,
104    pub category: SchemaType,
105    pub identity: bool,
106    pub read_only: bool,
107    pub auto_create: bool,
108    pub required: bool,
109    pub fixed: bool,
110    pub options: Option<Vec<SchemaOption>>,
111    pub hidden: bool,
112    pub popover: bool,
113    pub sortable: bool,
114    pub filterable: bool,
115    pub span: Option<u8>,
116    pub default_value: Option<serde_json::Value>,
117    pub hidden_values: Vec<String>,
118    pub max_width: Option<u16>,
119    pub combinations: Option<Vec<String>>,
120    pub search_model: Option<String>,
121}
122
123impl Schema {
124    pub fn new_id() -> Self {
125        Self {
126            name: "id".to_string(),
127            category: SchemaType::Number,
128            read_only: true,
129            required: true,
130            hidden: true,
131            auto_create: true,
132            ..Default::default()
133        }
134    }
135    pub fn new_status() -> Self {
136        Self {
137            name: "status".to_string(),
138            category: SchemaType::Status,
139            required: true,
140            default_value: Some(serde_json::json!(Status::Enabled as i8)),
141            ..Default::default()
142        }
143    }
144    pub fn new_remark() -> Self {
145        Self {
146            name: "remark".to_string(),
147            category: SchemaType::String,
148            required: true,
149            span: Some(2),
150            popover: true,
151            ..Default::default()
152        }
153    }
154    pub fn new_created() -> Self {
155        Self {
156            name: "created".to_string(),
157            category: SchemaType::Date,
158            read_only: true,
159            hidden: true,
160            auto_create: true,
161            ..Default::default()
162        }
163    }
164    pub fn new_modified() -> Self {
165        Self {
166            name: "modified".to_string(),
167            category: SchemaType::Date,
168            read_only: true,
169            sortable: true,
170            auto_create: true,
171            ..Default::default()
172        }
173    }
174    pub fn new_filterable_modified() -> Self {
175        let mut modified = Self::new_modified();
176        modified.filterable = true;
177        modified
178    }
179    pub fn new_user_search(name: impl Into<String>) -> Self {
180        Self {
181            name: name.into(),
182            category: SchemaType::Search,
183            search_model: Some("user".to_string()),
184            ..Default::default()
185        }
186    }
187    pub fn new_readonly_remark() -> Self {
188        Self {
189            name: "remark".to_string(),
190            category: SchemaType::String,
191            read_only: true,
192            popover: true,
193            ..Default::default()
194        }
195    }
196    pub fn new_name() -> Self {
197        Self {
198            name: "name".to_string(),
199            category: SchemaType::String,
200            required: true,
201            fixed: true,
202            ..Default::default()
203        }
204    }
205    pub fn new_effective_start_time() -> Self {
206        Self {
207            name: "effective_start_time".to_string(),
208            category: SchemaType::Date,
209            required: true,
210            ..Default::default()
211        }
212    }
213    pub fn new_effective_end_time() -> Self {
214        Self {
215            name: "effective_end_time".to_string(),
216            category: SchemaType::Date,
217            required: true,
218            ..Default::default()
219        }
220    }
221}
222
223#[derive(Debug, Clone, Deserialize, Serialize, Default)]
224pub struct SchemaView {
225    pub schemas: Vec<Schema>,
226    pub allow_edit: SchemaAllowEdit,
227    pub allow_create: SchemaAllowCreate,
228}