pointlock_store/projection/
schema.rs1use schemars::{JsonSchema, generate::SchemaSettings};
14use serde_json::Value;
15
16use super::{FlowGraphView, HumanInboxEntry, RunOverview, StepDossierView, TimelinePage};
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum ProjectionSchemaFamily {
23 FlowGraph,
25 RunTimeline,
27 StepDossier,
29 HumanInbox,
31 RunOverview,
33}
34
35pub const PROJECTION_SCHEMA_FAMILIES: [ProjectionSchemaFamily; 5] = [
37 ProjectionSchemaFamily::FlowGraph,
38 ProjectionSchemaFamily::RunTimeline,
39 ProjectionSchemaFamily::StepDossier,
40 ProjectionSchemaFamily::HumanInbox,
41 ProjectionSchemaFamily::RunOverview,
42];
43
44impl ProjectionSchemaFamily {
45 pub fn stem(self) -> &'static str {
47 match self {
48 ProjectionSchemaFamily::FlowGraph => "flow-graph-view",
49 ProjectionSchemaFamily::RunTimeline => "run-timeline",
50 ProjectionSchemaFamily::StepDossier => "step-dossier-view",
51 ProjectionSchemaFamily::HumanInbox => "human-inbox-entry",
52 ProjectionSchemaFamily::RunOverview => "run-overview",
53 }
54 }
55
56 pub fn title(self) -> &'static str {
58 match self {
59 ProjectionSchemaFamily::FlowGraph => "FlowGraphView",
60 ProjectionSchemaFamily::RunTimeline => "TimelinePage",
61 ProjectionSchemaFamily::StepDossier => "StepDossierView",
62 ProjectionSchemaFamily::HumanInbox => "HumanInboxEntry",
63 ProjectionSchemaFamily::RunOverview => "RunOverview",
64 }
65 }
66
67 pub fn schema_id(self) -> String {
69 format!("urn:pointlock:schema:projection:v1:{}", self.stem())
70 }
71}
72
73fn root_schema<T: JsonSchema>(family: ProjectionSchemaFamily) -> Value {
74 let settings = SchemaSettings::draft2020_12();
75 let mut generator = settings.into_generator();
76 let schema = generator.root_schema_for::<T>();
77 let mut doc = serde_json::to_value(&schema).expect("schema serializes to JSON");
78 if let Value::Object(root) = &mut doc {
79 root.insert("$id".to_owned(), Value::String(family.schema_id()));
80 root.insert("title".to_owned(), Value::String(family.title().to_owned()));
81 }
82 doc
83}
84
85pub fn projection_schema(family: ProjectionSchemaFamily) -> Value {
87 match family {
88 ProjectionSchemaFamily::FlowGraph => root_schema::<FlowGraphView>(family),
89 ProjectionSchemaFamily::RunTimeline => root_schema::<TimelinePage>(family),
90 ProjectionSchemaFamily::StepDossier => root_schema::<StepDossierView>(family),
91 ProjectionSchemaFamily::HumanInbox => root_schema::<HumanInboxEntry>(family),
92 ProjectionSchemaFamily::RunOverview => root_schema::<RunOverview>(family),
93 }
94}
95
96pub fn projection_schemas() -> Vec<(ProjectionSchemaFamily, Value)> {
98 PROJECTION_SCHEMA_FAMILIES
99 .iter()
100 .map(|&family| (family, projection_schema(family)))
101 .collect()
102}