use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
pub const META_PREFIX: &str = "_";
pub const SCHEMA_VERSION: u64 = 1;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum FieldType {
#[serde(rename = "string")]
String,
#[serde(rename = "int")]
Int,
#[serde(rename = "float")]
Float,
#[serde(rename = "bool")]
Bool,
#[serde(rename = "timestamp")]
Timestamp,
#[serde(rename = "enum")]
Enum,
#[serde(rename = "json")]
Json,
#[serde(rename = "string[]")]
StringArray,
#[serde(rename = "int[]")]
IntArray,
#[serde(rename = "float[]")]
FloatArray,
#[serde(rename = "bool[]")]
BoolArray,
#[serde(rename = "markdown")]
Markdown,
#[serde(rename = "image")]
Image,
}
impl FieldType {
pub fn is_array(self) -> bool {
matches!(
self,
FieldType::StringArray | FieldType::IntArray | FieldType::FloatArray | FieldType::BoolArray
)
}
pub fn element_type(self) -> Option<FieldType> {
match self {
FieldType::StringArray => Some(FieldType::String),
FieldType::IntArray => Some(FieldType::Int),
FieldType::FloatArray => Some(FieldType::Float),
FieldType::BoolArray => Some(FieldType::Bool),
_ => None,
}
}
pub fn is_sortable(self) -> bool {
matches!(
self,
FieldType::String | FieldType::Int | FieldType::Float | FieldType::Timestamp
)
}
pub fn has_virtual_path(self) -> bool {
matches!(self, FieldType::Markdown | FieldType::Image)
}
pub fn as_str(self) -> &'static str {
match self {
FieldType::String => "string",
FieldType::Int => "int",
FieldType::Float => "float",
FieldType::Bool => "bool",
FieldType::Timestamp => "timestamp",
FieldType::Enum => "enum",
FieldType::Json => "json",
FieldType::StringArray => "string[]",
FieldType::IntArray => "int[]",
FieldType::FloatArray => "float[]",
FieldType::BoolArray => "bool[]",
FieldType::Markdown => "markdown",
FieldType::Image => "image",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum IndexKind {
#[serde(rename = "exact")]
Exact,
#[serde(rename = "sorted")]
Sorted,
}
#[derive(Debug, Clone, PartialEq)]
pub enum DefaultValue {
Now,
Value(Value),
}
#[derive(Debug, Clone, PartialEq)]
pub struct FieldSpec {
pub field_type: FieldType,
pub required: bool,
pub unique: bool,
pub index: Option<IndexKind>,
pub fulltext: bool,
pub cypher: bool,
pub password_hash: bool,
pub values: Option<Vec<String>>,
pub default: Option<DefaultValue>,
pub addressable: bool,
}
impl FieldSpec {
pub fn new(field_type: FieldType) -> Self {
FieldSpec {
field_type,
required: false,
unique: false,
index: None,
fulltext: false,
cypher: false,
password_hash: false,
values: None,
default: None,
addressable: true,
}
}
pub fn has_virtual_path(&self) -> bool {
self.field_type.has_virtual_path() && self.addressable
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct TableSchema {
pub table: String,
pub revision: u32,
pub primary_key: String,
pub partition_by: Option<String>,
pub fields: BTreeMap<String, FieldSpec>,
}