specfold_core/model/
registry.rs1use super::doctype::{self, Form, KeyKind, TypeDef};
4use serde::{Deserialize, Serialize};
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone, Default, Deserialize, Serialize)]
9#[serde(deny_unknown_fields)]
10pub struct TypeOverride {
11 pub enabled: Option<bool>,
12 pub about: Option<String>,
13 pub key: Option<KeyKind>,
14 pub form: Option<Form>,
15 pub statuses: Option<Vec<String>>,
16 pub initial: Option<String>,
17 pub sealed: Option<bool>,
18 pub fields: Option<Vec<String>>,
19 pub template: Option<String>,
20 pub transitions: Option<BTreeMap<String, Vec<String>>>,
21 pub require_when: Option<BTreeMap<String, Vec<String>>>,
22}
23
24#[derive(Debug, Clone)]
25pub struct Registry {
26 pub types: Vec<TypeDef>,
27}
28
29fn apply(t: &mut TypeDef, o: &TypeOverride) {
30 if let Some(v) = &o.about {
31 t.about = v.clone();
32 }
33 if let Some(v) = o.key {
34 t.key = v;
35 }
36 if let Some(v) = o.form {
37 t.form = v;
38 }
39 if let Some(v) = &o.statuses {
40 t.statuses = v.clone();
41 }
42 if let Some(v) = &o.initial {
43 t.initial = v.clone();
44 }
45 if let Some(v) = o.sealed {
46 t.sealed = v;
47 }
48 if let Some(v) = &o.fields {
49 t.fields = v.clone();
50 }
51 if let Some(v) = &o.template {
52 t.template = v.clone();
53 }
54 if let Some(v) = &o.transitions {
55 t.transitions = v.clone();
56 }
57 if let Some(v) = &o.require_when {
58 t.require_when = v.clone();
59 }
60}
61
62impl Registry {
63 pub fn new(overrides: &BTreeMap<String, TypeOverride>) -> Self {
64 let mut types = doctype::builtin();
65 for (name, o) in overrides {
66 let pos = types.iter().position(|t| &t.name == name);
67 if o.enabled == Some(false) {
68 if let Some(p) = pos {
69 types.remove(p);
70 }
71 continue;
72 }
73 match pos {
74 Some(p) => apply(&mut types[p], o),
75 None => {
76 let mut t = doctype::custom(name);
77 apply(&mut t, o);
78 types.push(t);
79 }
80 }
81 }
82 Registry { types }
83 }
84
85 pub fn get(&self, name: &str) -> Option<&TypeDef> {
86 self.types.iter().find(|t| t.name == name)
87 }
88
89 pub fn names(&self) -> Vec<&str> {
90 self.types.iter().map(|t| t.name.as_str()).collect()
91 }
92}