schemars/json_schema_impls/
maps.rs

1use crate::_alloc_prelude::*;
2use crate::{json_schema, JsonSchema, Schema, SchemaGenerator};
3use alloc::borrow::Cow;
4use alloc::collections::BTreeMap;
5use serde_json::{json, Value};
6
7impl<K, V> JsonSchema for BTreeMap<K, V>
8where
9    K: JsonSchema,
10    V: JsonSchema,
11{
12    inline_schema!();
13
14    fn schema_name() -> Cow<'static, str> {
15        Cow::Owned(if K::schema_id() == <str>::schema_id() {
16            format!("Map_of_{}", V::schema_name())
17        } else {
18            format!("Map_from_{}_to_{}", K::schema_name(), V::schema_name())
19        })
20    }
21
22    fn schema_id() -> Cow<'static, str> {
23        Cow::Owned(if K::schema_id() == <str>::schema_id() {
24            format!("Map<{}>", V::schema_id())
25        } else {
26            format!("Map<{}, {}>", K::schema_id(), V::schema_id())
27        })
28    }
29
30    fn json_schema(generator: &mut SchemaGenerator) -> Schema {
31        let key_schema = K::json_schema(generator);
32        let value_schema = generator.subschema_for::<V>();
33
34        let mut map_schema = json_schema!({
35            "type": "object",
36        });
37
38        let key_pattern = key_schema.get("pattern").and_then(Value::as_str);
39        let key_type = key_schema.get("type").and_then(Value::as_str);
40        let key_minimum = key_schema.get("minimum").and_then(Value::as_u64);
41
42        let pattern = match (key_pattern, key_type) {
43            (Some(pattern), Some("string")) => pattern,
44            (_, Some("integer")) if key_minimum == Some(0) => r"^\d+$",
45            (_, Some("integer")) => r"^-?\d+$",
46            _ => {
47                map_schema.insert("additionalProperties".to_owned(), value_schema.to_value());
48                return map_schema;
49            }
50        };
51
52        map_schema.insert(
53            "patternProperties".to_owned(),
54            json!({ pattern: value_schema }),
55        );
56        map_schema.insert("additionalProperties".to_owned(), Value::Bool(false));
57
58        map_schema
59    }
60}
61
62#[cfg(feature = "std")]
63forward_impl!((<K: JsonSchema, V: JsonSchema, H> JsonSchema for std::collections::HashMap<K, V, H>) => BTreeMap<K, V>);