schemars/json_schema_impls/
maps.rs1use 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>);