Improve flatten
behavioure with additionalProperties
This commit is contained in:
parent
85626ab3a3
commit
30a9a384e2
3 changed files with 127 additions and 5 deletions
|
@ -185,17 +185,23 @@ pub fn flatten(schema: &mut Schema, other: Schema) {
|
|||
Err(true) => {
|
||||
schema
|
||||
.ensure_object()
|
||||
.entry("additionalProperties")
|
||||
.or_insert(true.into());
|
||||
.insert("additionalProperties".to_owned(), true.into());
|
||||
}
|
||||
Ok(obj2) => {
|
||||
let obj1 = schema.ensure_object();
|
||||
|
||||
for (key, value2) in obj2 {
|
||||
match obj1.entry(key) {
|
||||
Entry::Vacant(vacant) => {
|
||||
Entry::Vacant(vacant) => match vacant.key().as_str() {
|
||||
"additionalProperties" | "unevaluatedProperties" => {
|
||||
if value2 != Value::Bool(false) {
|
||||
vacant.insert(value2);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
vacant.insert(value2);
|
||||
}
|
||||
},
|
||||
Entry::Occupied(occupied) => {
|
||||
match occupied.key().as_str() {
|
||||
"required" => {
|
||||
|
@ -212,6 +218,13 @@ pub fn flatten(schema: &mut Schema, other: Schema) {
|
|||
}
|
||||
}
|
||||
}
|
||||
"additionalProperties" | "unevaluatedProperties" => {
|
||||
// Even if an outer type has `deny_unknown_fields`, unknown fields
|
||||
// may be accepted by the flattened type
|
||||
if occupied.get() == &Value::Bool(false) {
|
||||
*occupied.into_mut() = value2;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// leave the original value as it is (don't modify `schema`)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"title": "Tuple_of_OuterAllowUnknownFields_and_MiddleDenyUnknownFields",
|
||||
"type": "array",
|
||||
"prefixItems": [
|
||||
{
|
||||
"$ref": "#/$defs/OuterAllowUnknownFields"
|
||||
},
|
||||
{
|
||||
"$ref": "#/$defs/MiddleDenyUnknownFields"
|
||||
}
|
||||
],
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"$defs": {
|
||||
"OuterAllowUnknownFields": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"outer_field": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"middle_field": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"inner_field": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"outer_field",
|
||||
"middle_field",
|
||||
"inner_field"
|
||||
]
|
||||
},
|
||||
"MiddleDenyUnknownFields": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"middle_field": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"inner_field": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"middle_field",
|
||||
"inner_field"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,6 +76,24 @@ struct FlattenMap {
|
|||
value: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(rename = "FlattenValue", deny_unknown_fields)]
|
||||
struct FlattenValueDenyUnknownFields {
|
||||
flag: bool,
|
||||
#[serde(flatten)]
|
||||
value: Value,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(JsonSchema)]
|
||||
#[schemars(rename = "FlattenValue", deny_unknown_fields)]
|
||||
struct FlattenMapDenyUnknownFields {
|
||||
flag: bool,
|
||||
#[serde(flatten)]
|
||||
value: BTreeMap<String, Value>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flattened_value() -> TestResult {
|
||||
test_default_generated_schema::<FlattenValue>("flattened_value")
|
||||
|
@ -86,3 +104,42 @@ fn test_flattened_map() -> TestResult {
|
|||
// intentionally using the same file as test_flattened_value, as the schema should be identical
|
||||
test_default_generated_schema::<FlattenMap>("flattened_value")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flattened_value_deny_unknown_fields() -> TestResult {
|
||||
// intentionally using the same file as test_flattened_value, as the schema should be identical
|
||||
test_default_generated_schema::<FlattenValueDenyUnknownFields>("flattened_value")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flattened_map_deny_unknown_fields() -> TestResult {
|
||||
// intentionally using the same file as test_flattened_value, as the schema should be identical
|
||||
test_default_generated_schema::<FlattenMapDenyUnknownFields>("flattened_value")
|
||||
}
|
||||
|
||||
#[derive(JsonSchema)]
|
||||
pub struct OuterAllowUnknownFields {
|
||||
pub outer_field: bool,
|
||||
#[serde(flatten)]
|
||||
pub middle: MiddleDenyUnknownFields,
|
||||
}
|
||||
|
||||
#[derive(JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct MiddleDenyUnknownFields {
|
||||
pub middle_field: bool,
|
||||
#[serde(flatten)]
|
||||
pub inner: InnerAllowUnknownFields,
|
||||
}
|
||||
|
||||
#[derive(JsonSchema)]
|
||||
pub struct InnerAllowUnknownFields {
|
||||
pub inner_field: bool,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flattened_struct_deny_unknown_fields() -> TestResult {
|
||||
test_default_generated_schema::<(OuterAllowUnknownFields, MiddleDenyUnknownFields)>(
|
||||
"test_flattened_struct_deny_unknown_fields",
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue