Fix some cases of unsatisfiable schemas when flattening enums (#325)

Addresses #164 and #165
This commit is contained in:
Graham Esau 2024-08-22 19:56:31 +01:00 committed by GitHub
parent 9683d18e67
commit 9658c42d6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 553 additions and 127 deletions

View file

@ -1,10 +1,9 @@
mod util;
use schemars::JsonSchema;
use schemars::{generate::SchemaSettings, JsonSchema};
use util::*;
#[allow(dead_code)]
#[derive(JsonSchema)]
#[schemars(rename = "Flat")]
struct Flat {
f: f32,
#[schemars(flatten)]
@ -58,3 +57,33 @@ enum Enum5 {
fn test_flat_schema() -> TestResult {
test_default_generated_schema::<Flat>("enum_flatten")
}
#[allow(dead_code)]
#[derive(JsonSchema)]
#[schemars(deny_unknown_fields)]
struct FlatDenyUnknownFields {
f: f32,
#[schemars(flatten)]
e1: Enum1,
#[schemars(flatten)]
e2: Enum2,
#[schemars(flatten)]
e3: Enum3,
#[schemars(flatten)]
e4: Enum4,
#[schemars(flatten)]
e5: Enum5,
}
#[test]
fn test_flat_schema_duf() -> TestResult {
test_default_generated_schema::<FlatDenyUnknownFields>("enum_flatten_duf")
}
#[test]
fn test_flat_schema_duf_draft07() -> TestResult {
test_generated_schema::<FlatDenyUnknownFields>(
"enum_flatten_duf_draft07",
SchemaSettings::draft07(),
)
}

View file

@ -23,8 +23,7 @@
},
"required": [
"B"
],
"additionalProperties": false
]
},
{
"type": "object",
@ -35,8 +34,7 @@
},
"required": [
"S"
],
"additionalProperties": false
]
}
]
},
@ -53,8 +51,7 @@
},
"required": [
"U"
],
"additionalProperties": false
]
},
{
"type": "object",
@ -66,8 +63,7 @@
},
"required": [
"F"
],
"additionalProperties": false
]
}
]
},
@ -82,8 +78,7 @@
},
"required": [
"B2"
],
"additionalProperties": false
]
},
{
"type": "object",
@ -94,8 +89,7 @@
},
"required": [
"S2"
],
"additionalProperties": false
]
}
]
},
@ -112,8 +106,7 @@
},
"required": [
"U2"
],
"additionalProperties": false
]
},
{
"type": "object",
@ -125,8 +118,7 @@
},
"required": [
"F2"
],
"additionalProperties": false
]
}
]
}
@ -141,8 +133,7 @@
},
"required": [
"B3"
],
"additionalProperties": false
]
},
{
"type": "object",
@ -153,8 +144,7 @@
},
"required": [
"S3"
],
"additionalProperties": false
]
}
]
}

View file

@ -0,0 +1,151 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "FlatDenyUnknownFields",
"type": "object",
"properties": {
"f": {
"type": "number",
"format": "float"
}
},
"required": [
"f"
],
"unevaluatedProperties": false,
"allOf": [
{
"oneOf": [
{
"type": "object",
"properties": {
"B": {
"type": "boolean"
}
},
"required": [
"B"
]
},
{
"type": "object",
"properties": {
"S": {
"type": "string"
}
},
"required": [
"S"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"U": {
"type": "integer",
"format": "uint32",
"minimum": 0
}
},
"required": [
"U"
]
},
{
"type": "object",
"properties": {
"F": {
"type": "number",
"format": "double"
}
},
"required": [
"F"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"B2": {
"type": "boolean"
}
},
"required": [
"B2"
]
},
{
"type": "object",
"properties": {
"S2": {
"type": "string"
}
},
"required": [
"S2"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"U2": {
"type": "integer",
"format": "uint32",
"minimum": 0
}
},
"required": [
"U2"
]
},
{
"type": "object",
"properties": {
"F2": {
"type": "number",
"format": "double"
}
},
"required": [
"F2"
]
}
]
}
],
"oneOf": [
{
"type": "object",
"properties": {
"B3": {
"type": "boolean"
}
},
"required": [
"B3"
]
},
{
"type": "object",
"properties": {
"S3": {
"type": "string"
}
},
"required": [
"S3"
]
}
]
}

View file

@ -0,0 +1,161 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "FlatDenyUnknownFields",
"type": "object",
"properties": {
"f": {
"type": "number",
"format": "float"
},
"B": true,
"B2": true,
"B3": true,
"F": true,
"F2": true,
"S": true,
"S2": true,
"S3": true,
"U": true,
"U2": true
},
"required": [
"f"
],
"allOf": [
{
"oneOf": [
{
"type": "object",
"properties": {
"B": {
"type": "boolean"
}
},
"required": [
"B"
]
},
{
"type": "object",
"properties": {
"S": {
"type": "string"
}
},
"required": [
"S"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"U": {
"type": "integer",
"format": "uint32",
"minimum": 0
}
},
"required": [
"U"
]
},
{
"type": "object",
"properties": {
"F": {
"type": "number",
"format": "double"
}
},
"required": [
"F"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"B2": {
"type": "boolean"
}
},
"required": [
"B2"
]
},
{
"type": "object",
"properties": {
"S2": {
"type": "string"
}
},
"required": [
"S2"
]
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"U2": {
"type": "integer",
"format": "uint32",
"minimum": 0
}
},
"required": [
"U2"
]
},
{
"type": "object",
"properties": {
"F2": {
"type": "number",
"format": "double"
}
},
"required": [
"F2"
]
}
]
}
],
"oneOf": [
{
"type": "object",
"properties": {
"B3": {
"type": "boolean"
}
},
"required": [
"B3"
]
},
{
"type": "object",
"properties": {
"S3": {
"type": "string"
}
},
"required": [
"S3"
]
}
],
"additionalProperties": false
}

View file

@ -76,24 +76,6 @@ 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")
@ -105,18 +87,6 @@ fn test_flattened_map() -> TestResult {
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,