1use crate::evaluator::DatabaseEvaluator;
4use crate::owner_ref::OwnershipConfig;
5use crate::privacy::PolicyEvaluator;
6use crate::ttl::SchemaTtlPolicy;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize, Default)]
11pub struct SchemaPolicyRule {
12 pub name: String,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub description: Option<String>,
15 #[serde(skip, default)]
16 pub evaluator: Option<&'static dyn PolicyEvaluator>,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, Default)]
21pub struct SchemaPolicyRules {
22 #[serde(default, skip_serializing_if = "Vec::is_empty")]
23 pub always_allow: Vec<SchemaPolicyRule>,
24 #[serde(default, skip_serializing_if = "Vec::is_empty")]
25 pub allow: Vec<SchemaPolicyRule>,
26 #[serde(default, skip_serializing_if = "Vec::is_empty")]
27 pub block: Vec<SchemaPolicyRule>,
28 #[serde(default, skip_serializing_if = "Vec::is_empty")]
29 pub always_block: Vec<SchemaPolicyRule>,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, Default)]
34pub struct SchemaPolicies {
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub read: Option<SchemaPolicyRules>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub create: Option<SchemaPolicyRules>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 pub update: Option<SchemaPolicyRules>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub delete: Option<SchemaPolicyRules>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct SchemaPrivacy {
48 pub read: String,
49 pub write: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct ForeignKeyRef {
55 pub ref_table: String,
56 pub field: String,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct SchemaField {
62 pub name: String,
63 pub field_type: String,
64 pub primary: bool,
65 pub nullable: bool,
66 pub indexed: bool,
67 #[serde(default, skip_serializing_if = "is_false")]
68 pub unique: bool,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub default: Option<String>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub fk: Option<ForeignKeyRef>,
73 #[serde(default, skip_serializing_if = "Vec::is_empty")]
74 pub validations: Vec<String>,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub policies: Option<SchemaPolicies>,
77 #[serde(default, skip_serializing_if = "is_false")]
78 pub encrypted: bool,
79 #[serde(default, skip_serializing_if = "Vec::is_empty")]
80 pub enum_variants: Vec<String>,
81 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub enum_type: Option<String>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct SchemaEdge {
88 pub from_field: String,
89 pub to_table: String,
90 pub label: String,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct SchemaConnection {
96 pub name: String,
97 pub from_table: String,
98 pub from_field: String,
99 pub to_table: String,
100 pub cardinality: String,
101 pub required: bool,
102 pub on_delete: String,
103 pub label: String,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub model_path: Option<String>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub reverse_field: Option<String>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub edge_table: Option<String>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub target_trait: Option<String>,
112}
113
114impl From<SchemaEdge> for SchemaConnection {
115 fn from(edge: SchemaEdge) -> Self {
116 let label = edge.label.clone();
117 Self {
118 name: edge.from_field.clone(),
119 from_table: String::new(),
120 from_field: edge.from_field,
121 to_table: edge.to_table,
122 cardinality: "HasOne".to_string(),
123 required: true,
124 on_delete: "Cascade".to_string(),
125 label,
126 model_path: None,
127 reverse_field: None,
128 edge_table: None,
129 target_trait: None,
130 }
131 }
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
136pub struct SchemaMeta {
137 pub retention: String,
138 pub row_count: u64,
139 pub owner: String,
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub description: Option<String>,
142}
143
144#[derive(Debug, Clone, Serialize)]
146pub struct Schema {
147 pub name: String,
148 pub version: String,
149 pub databases: Vec<String>,
150 #[serde(skip)]
151 pub database_evaluator: &'static dyn DatabaseEvaluator,
152 pub privacy: SchemaPrivacy,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub policies: Option<SchemaPolicies>,
155 pub fields: Vec<SchemaField>,
156 #[serde(default, skip_serializing_if = "Vec::is_empty")]
157 pub edges: Vec<SchemaEdge>,
158 #[serde(default, skip_serializing_if = "Vec::is_empty")]
159 pub connections: Vec<SchemaConnection>,
160 #[serde(default, skip_serializing_if = "Vec::is_empty")]
161 pub side_effects: Vec<String>,
162 #[serde(default, skip_serializing_if = "Vec::is_empty")]
163 pub iters: Vec<String>,
164 #[serde(default, skip_serializing_if = "Vec::is_empty")]
165 pub composite_key: Vec<String>,
166 #[serde(default, skip_serializing_if = "Vec::is_empty")]
167 pub traits: Vec<String>,
168 #[serde(skip_serializing_if = "Option::is_none")]
169 pub ttl: Option<SchemaTtlPolicy>,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub ownership: Option<OwnershipConfig>,
172 pub meta: SchemaMeta,
173}
174
175fn is_false(value: &bool) -> bool {
176 !*value
177}