reductionml_core/
config_schema.rs1use schemars::{
2 gen::SchemaGenerator,
3 schema::{RootSchema, Schema, SchemaObject},
4 schema_for,
5};
6
7use crate::{reduction_factory::ReductionFactory, workspace::Configuration};
8
9pub struct ConfigSchema {
10 schema: RootSchema,
11}
12
13impl Default for ConfigSchema {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18
19impl ConfigSchema {
20 pub fn new() -> Self {
21 let mut schema = schema_for!(Configuration);
22
23 let mut any_reduction_config = SchemaObject::default();
25 any_reduction_config.subschemas().one_of = Some(vec![]);
26
27 schema.definitions.insert(
28 "any_reduction_config".to_owned(),
29 Schema::Object(any_reduction_config),
30 );
31
32 let mut schema_schema: SchemaObject = SchemaObject::default();
34 schema_schema.string().pattern = Some(".*".to_owned());
35 schema
36 .schema
37 .object()
38 .properties
39 .insert("$schema".to_owned(), schema_schema.into());
40
41 Self { schema }
42 }
43
44 pub fn schema(&self) -> &RootSchema {
45 &self.schema
46 }
47
48 pub fn add_reduction(&mut self, reduction_factory: &dyn ReductionFactory) {
49 let typename_constant = schemars::schema::SchemaObject {
50 const_value: Some(reduction_factory.typename().as_ref().into()),
51 ..Default::default()
52 };
53
54 let mut reduction_config_schema = SchemaObject::default();
55 reduction_config_schema
56 .object()
57 .properties
58 .insert("typename".to_owned(), Schema::Object(typename_constant));
59
60 let reductions_inner_schema = reduction_factory.get_config_schema();
61 reduction_config_schema.object().properties.insert(
62 "config".to_owned(),
63 Schema::Object(reductions_inner_schema.schema),
64 );
65 reduction_config_schema.object().additional_properties =
67 Some(Box::new(Schema::Bool(false)));
68
69 self.schema.definitions.insert(
70 reduction_factory.typename().as_ref().into(),
71 Schema::Object(reduction_config_schema),
72 );
73
74 match self
75 .schema
76 .definitions
77 .get_mut("any_reduction_config")
78 .unwrap()
79 {
80 Schema::Object(any_reduction_config) => {
81 let new_reduction_ref = schemars::schema::SchemaObject {
82 reference: Some(format!("#/definitions/{}", reduction_factory.typename())),
83 ..Default::default()
84 };
85 any_reduction_config
86 .subschemas()
87 .one_of
88 .as_mut()
89 .unwrap()
90 .push(Schema::Object(new_reduction_ref));
91 }
92 _ => panic!("any_reduction_config is not an object"),
93 }
94
95 self.schema
97 .definitions
98 .extend(reductions_inner_schema.definitions);
99
100 }
102}
103
104pub(crate) fn gen_json_reduction_config_schema(_gen: &mut SchemaGenerator) -> Schema {
105 schemars::schema::SchemaObject {
106 reference: Some("#/definitions/any_reduction_config".to_owned()),
107 ..Default::default()
108 }
109 .into()
110}