hayson_engine/schema/
types.rs1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6pub const META_PREFIX: &str = "_";
7
8pub const SCHEMA_VERSION: u64 = 1;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum FieldType {
13 #[serde(rename = "string")]
14 String,
15 #[serde(rename = "int")]
16 Int,
17 #[serde(rename = "float")]
18 Float,
19 #[serde(rename = "bool")]
20 Bool,
21 #[serde(rename = "timestamp")]
22 Timestamp,
23 #[serde(rename = "enum")]
24 Enum,
25 #[serde(rename = "json")]
26 Json,
27 #[serde(rename = "string[]")]
28 StringArray,
29 #[serde(rename = "int[]")]
30 IntArray,
31 #[serde(rename = "float[]")]
32 FloatArray,
33 #[serde(rename = "bool[]")]
34 BoolArray,
35 #[serde(rename = "markdown")]
36 Markdown,
37 #[serde(rename = "image")]
38 Image,
39}
40
41impl FieldType {
42 pub fn is_array(self) -> bool {
43 matches!(
44 self,
45 FieldType::StringArray | FieldType::IntArray | FieldType::FloatArray | FieldType::BoolArray
46 )
47 }
48
49 pub fn element_type(self) -> Option<FieldType> {
50 match self {
51 FieldType::StringArray => Some(FieldType::String),
52 FieldType::IntArray => Some(FieldType::Int),
53 FieldType::FloatArray => Some(FieldType::Float),
54 FieldType::BoolArray => Some(FieldType::Bool),
55 _ => None,
56 }
57 }
58
59 pub fn is_sortable(self) -> bool {
60 matches!(
61 self,
62 FieldType::String | FieldType::Int | FieldType::Float | FieldType::Timestamp
63 )
64 }
65
66 pub fn has_virtual_path(self) -> bool {
70 matches!(self, FieldType::Markdown | FieldType::Image)
71 }
72
73 pub fn as_str(self) -> &'static str {
74 match self {
75 FieldType::String => "string",
76 FieldType::Int => "int",
77 FieldType::Float => "float",
78 FieldType::Bool => "bool",
79 FieldType::Timestamp => "timestamp",
80 FieldType::Enum => "enum",
81 FieldType::Json => "json",
82 FieldType::StringArray => "string[]",
83 FieldType::IntArray => "int[]",
84 FieldType::FloatArray => "float[]",
85 FieldType::BoolArray => "bool[]",
86 FieldType::Markdown => "markdown",
87 FieldType::Image => "image",
88 }
89 }
90}
91
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
93pub enum IndexKind {
94 #[serde(rename = "exact")]
95 Exact,
96 #[serde(rename = "sorted")]
97 Sorted,
98}
99
100#[derive(Debug, Clone, PartialEq)]
101pub enum DefaultValue {
102 Now,
103 Value(Value),
104}
105
106#[derive(Debug, Clone, PartialEq)]
107pub struct FieldSpec {
108 pub field_type: FieldType,
109 pub required: bool,
110 pub unique: bool,
111 pub index: Option<IndexKind>,
112 pub fulltext: bool,
113 pub cypher: bool,
115 pub password_hash: bool,
118 pub values: Option<Vec<String>>,
119 pub default: Option<DefaultValue>,
120 pub addressable: bool,
124}
125
126impl FieldSpec {
127 pub fn new(field_type: FieldType) -> Self {
128 FieldSpec {
129 field_type,
130 required: false,
131 unique: false,
132 index: None,
133 fulltext: false,
134 cypher: false,
135 password_hash: false,
136 values: None,
137 default: None,
138 addressable: true,
139 }
140 }
141
142 pub fn has_virtual_path(&self) -> bool {
146 self.field_type.has_virtual_path() && self.addressable
147 }
148}
149
150#[derive(Debug, Clone, PartialEq)]
151pub struct TableSchema {
152 pub table: String,
153 pub revision: u32,
154 pub primary_key: String,
155 pub partition_by: Option<String>,
156 pub fields: BTreeMap<String, FieldSpec>,
157}