1use serde::Serialize;
6
7use crate::refs::PathSeg;
8use crate::typ::Typ;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
11pub enum CollectionKind {
12 Entity,
14 SecondaryIndex,
16 Denormalized,
18 Counters,
20 Standalone,
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
25pub enum OnMissing {
26 Error,
28 Warn,
30 AllowMissing,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
35pub enum RelationKind {
36 Fk {
37 field_path: Vec<PathSeg>,
39 brand: String,
40 on_missing: OnMissing,
41 validated: bool,
44 },
45 Index,
47 Denorm,
49 Counter { field: String },
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
55pub enum ValueModel {
56 Zero,
58 Typed,
60 VarTyped,
62}
63
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
66pub enum CollectionShape {
67 Tree,
69 Map,
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
75pub enum StorageBackend {
76 Bitcask,
78 Fixed,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
84pub struct StorageClass {
85 pub model: ValueModel,
86 pub shape: CollectionShape,
87 pub backend: StorageBackend,
88}
89
90#[derive(Debug, Clone, Serialize)]
91pub struct CollectionNode {
92 pub name: String,
93 pub kind: CollectionKind,
94 pub ty: Typ,
96 pub key_ty: Option<Typ>,
98 pub self_brand: Option<String>,
100 pub storage: Option<StorageClass>,
102}
103
104#[derive(Debug, Clone, Serialize)]
105pub struct RelationEdge {
106 pub from: String,
107 pub to: String,
108 pub kind: RelationKind,
109}
110
111#[derive(Debug, Clone, Serialize, Default)]
112pub struct SchemaGraph {
113 pub collections: Vec<CollectionNode>,
114 pub relations: Vec<RelationEdge>,
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use crate::scalar::ScalarTyp;
121
122 #[test]
123 fn graph_serializes_to_json() {
124 let g = SchemaGraph {
125 collections: vec![CollectionNode {
126 name: "users".into(),
127 kind: CollectionKind::Entity,
128 ty: Typ::Scalar(ScalarTyp::U64),
129 key_ty: None,
130 self_brand: Some("USR".into()),
131 storage: None,
132 }],
133 relations: vec![RelationEdge {
134 from: "messages".into(),
135 to: "users".into(),
136 kind: RelationKind::Fk {
137 field_path: vec![PathSeg::Field("sender_id")],
138 brand: "USR".into(),
139 on_missing: OnMissing::Error,
140 validated: true,
141 },
142 }],
143 };
144 let json = serde_json::to_string(&g).expect("serialize");
145 assert!(json.contains("\"users\""));
146 assert!(json.contains("\"sender_id\""));
147 }
148}