json_schema.rs

 1use schemars::schema::{ArrayValidation, InstanceType, RootSchema, Schema, SchemaObject};
 2use serde_json::Value;
 3
 4pub struct SettingsJsonSchemaParams<'a> {
 5    pub staff_mode: bool,
 6    pub language_names: &'a [String],
 7    pub font_names: &'a [String],
 8}
 9
10impl<'a> SettingsJsonSchemaParams<'a> {
11    pub fn font_family_schema(&self) -> Schema {
12        let available_fonts: Vec<_> = self.font_names.iter().cloned().map(Value::String).collect();
13
14        SchemaObject {
15            instance_type: Some(InstanceType::String.into()),
16            enum_values: Some(available_fonts),
17            ..Default::default()
18        }
19        .into()
20    }
21
22    pub fn font_fallback_schema(&self) -> Schema {
23        SchemaObject {
24            instance_type: Some(InstanceType::Array.into()),
25            array: Some(Box::new(ArrayValidation {
26                items: Some(schemars::schema::SingleOrVec::Single(Box::new(
27                    self.font_family_schema(),
28                ))),
29                unique_items: Some(true),
30                ..Default::default()
31            })),
32            ..Default::default()
33        }
34        .into()
35    }
36}
37
38type PropertyName<'a> = &'a str;
39type ReferencePath<'a> = &'a str;
40
41/// Modifies the provided [`RootSchema`] by adding references to all of the specified properties.
42///
43/// # Examples
44///
45/// ```
46/// # let root_schema = RootSchema::default();
47/// add_references_to_properties(&mut root_schema, &[
48///     ("property_a", "#/definitions/DefinitionA"),
49///     ("property_b", "#/definitions/DefinitionB"),
50/// ])
51/// ```
52pub fn add_references_to_properties(
53    root_schema: &mut RootSchema,
54    properties_with_references: &[(PropertyName, ReferencePath)],
55) {
56    for (property, definition) in properties_with_references {
57        let Some(schema) = root_schema.schema.object().properties.get_mut(*property) else {
58            log::warn!("property '{property}' not found in JSON schema");
59            continue;
60        };
61
62        match schema {
63            Schema::Object(schema) => {
64                schema.reference = Some(definition.to_string());
65            }
66            Schema::Bool(_) => {
67                // Boolean schemas can't have references.
68            }
69        }
70    }
71}