Skip to content

Commit

Permalink
Fix multiple enum flatten
Browse files Browse the repository at this point in the history
  • Loading branch information
rlebran committed Jun 25, 2024
1 parent 91ee3f9 commit f6b660e
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
17 changes: 17 additions & 0 deletions schemars/src/_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,16 @@ pub fn apply_inner_validation(schema: &mut Schema, f: fn(&mut Schema) -> ()) {
pub fn flatten(schema: &mut Schema, other: Schema) {
if let Value::Object(obj2) = other.to_value() {
let obj1 = schema.ensure_object();
eprintln!("obj1: {:?}, obj2: {:?}", obj1, obj2);

for (key, value2) in obj2 {
eprintln!("key: {:?}, value2: {:?}", key, value2);
match obj1.entry(key) {
Entry::Vacant(vacant) => {
vacant.insert(value2);
}
Entry::Occupied(mut occupied) => {
eprintln!("====> occupied");
match occupied.key().as_str() {
// This special "type" handling can probably be removed once the enum variant `with`/`schema_with` behaviour is fixed
"type" => match (occupied.get_mut(), value2) {
Expand Down Expand Up @@ -220,6 +223,20 @@ pub fn flatten(schema: &mut Schema, other: Schema) {
}
}
}
"oneOf" => {
if let a1 @ Value::Array(_) = occupied.get().clone() {
occupied.remove();
let all_of = Value::Array(vec![
json!({
"oneOf": a1
}),
json!({
"oneOf": value2
}),
]);
obj1.insert("allOf".to_string(), all_of);
}
}
_ => {
// leave the original value as it is (don't modify `schema`)
}
Expand Down
33 changes: 33 additions & 0 deletions schemars/tests/enum_flatten.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
mod util;
use schemars::JsonSchema;
use util::*;

#[allow(dead_code)]
#[derive(JsonSchema)]
#[schemars(rename = "Flat")]
struct Flat {
f: f32,
#[schemars(flatten)]
e1: Enum1,
#[schemars(flatten)]
e2: Enum2,
}

#[allow(dead_code)]
#[derive(JsonSchema)]
enum Enum1 {
B(bool),
S(String),
}

#[allow(dead_code)]
#[derive(JsonSchema)]
enum Enum2 {
U(u32),
F(f64),
}

#[test]
fn test_flat_schema() -> TestResult {
test_default_generated_schema::<Flat>("enum_flatten")
}
75 changes: 75 additions & 0 deletions schemars/tests/expected/enum_flatten.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Flat",
"type": "object",
"properties": {
"f": {
"type": "number",
"format": "float"
}
},
"required": [
"f"
],
"allOf": [
{
"oneOf": [
{
"type": "object",
"properties": {
"B": {
"type": "boolean"
}
},
"required": [
"B"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"S": {
"type": "string"
}
},
"required": [
"S"
],
"additionalProperties": false
}
]
},
{
"oneOf": [
{
"type": "object",
"properties": {
"U": {
"type": "integer",
"format": "uint32",
"minimum": 0
}
},
"required": [
"U"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"F": {
"type": "number",
"format": "double"
}
},
"required": [
"F"
],
"additionalProperties": false
}
]
}
]
}

0 comments on commit f6b660e

Please sign in to comment.