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) => {
|
Err(true) => {
|
||||||
schema
|
schema
|
||||||
.ensure_object()
|
.ensure_object()
|
||||||
.entry("additionalProperties")
|
.insert("additionalProperties".to_owned(), true.into());
|
||||||
.or_insert(true.into());
|
|
||||||
}
|
}
|
||||||
Ok(obj2) => {
|
Ok(obj2) => {
|
||||||
let obj1 = schema.ensure_object();
|
let obj1 = schema.ensure_object();
|
||||||
|
|
||||||
for (key, value2) in obj2 {
|
for (key, value2) in obj2 {
|
||||||
match obj1.entry(key) {
|
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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
vacant.insert(value2);
|
||||||
|
}
|
||||||
|
},
|
||||||
Entry::Occupied(occupied) => {
|
Entry::Occupied(occupied) => {
|
||||||
match occupied.key().as_str() {
|
match occupied.key().as_str() {
|
||||||
"required" => {
|
"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`)
|
// 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>,
|
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]
|
#[test]
|
||||||
fn test_flattened_value() -> TestResult {
|
fn test_flattened_value() -> TestResult {
|
||||||
test_default_generated_schema::<FlattenValue>("flattened_value")
|
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
|
// intentionally using the same file as test_flattened_value, as the schema should be identical
|
||||||
test_default_generated_schema::<FlattenMap>("flattened_value")
|
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