kotoba_core/ir/
catalog.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use crate::types::*;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct PropertyDef {
10 pub name: PropertyKey,
11 pub type_: ValueType,
12 pub nullable: bool,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub default: Option<Value>,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub enum ValueType {
20 #[serde(rename = "null")]
21 Null,
22 #[serde(rename = "bool")]
23 Bool,
24 #[serde(rename = "int")]
25 Int,
26 #[serde(rename = "float")]
27 Float,
28 #[serde(rename = "string")]
29 String,
30 #[serde(rename = "list")]
31 List(Box<ValueType>),
32 #[serde(rename = "map")]
33 Map,
34}
35
36impl PartialEq for ValueType {
37 fn eq(&self, other: &Self) -> bool {
38 match (self, other) {
39 (ValueType::Null, ValueType::Null) => true,
40 (ValueType::Bool, ValueType::Bool) => true,
41 (ValueType::Int, ValueType::Int) => true,
42 (ValueType::Float, ValueType::Float) => true,
43 (ValueType::String, ValueType::String) => true,
44 (ValueType::List(a), ValueType::List(b)) => a == b,
45 (ValueType::Map, ValueType::Map) => true,
46 _ => false,
47 }
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub struct LabelDef {
54 pub name: Label,
55 pub properties: Vec<PropertyDef>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub super_labels: Option<Vec<Label>>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct IndexDef {
63 pub name: String,
64 pub label: Label,
65 pub properties: Vec<PropertyKey>,
66 pub unique: bool,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct Invariant {
72 pub name: String,
73 pub expr: String, pub message: String,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct Catalog {
80 pub labels: HashMap<Label, LabelDef>,
81 pub indexes: Vec<IndexDef>,
82 pub invariants: Vec<Invariant>,
83}
84
85impl Catalog {
86 pub fn empty() -> Self {
88 Self {
89 labels: HashMap::new(),
90 indexes: Vec::new(),
91 invariants: Vec::new(),
92 }
93 }
94
95 pub fn add_label(&mut self, def: LabelDef) {
97 self.labels.insert(def.name.clone(), def);
98 }
99
100 pub fn add_index(&mut self, def: IndexDef) {
102 self.indexes.push(def);
103 }
104
105 pub fn add_invariant(&mut self, inv: Invariant) {
107 self.invariants.push(inv);
108 }
109
110 pub fn get_label(&self, name: &Label) -> Option<&LabelDef> {
112 self.labels.get(name)
113 }
114
115 pub fn get_property_def(&self, label: &Label, prop: &PropertyKey) -> Option<&PropertyDef> {
117 self.labels.get(label)?
118 .properties.iter()
119 .find(|p| p.name == *prop)
120 }
121
122 pub fn has_property(&self, label: &Label, prop: &PropertyKey) -> bool {
124 self.get_property_def(label, prop).is_some()
125 }
126}