Skip to content

Commit e67495b

Browse files
committed
Improve optional enum flattening behaviour
1 parent e873af2 commit e67495b

10 files changed

Lines changed: 1475 additions & 8 deletions

schemars/src/_private/mod.rs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,6 @@ pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
5353
) -> Schema {
5454
/// Non-generic inner function to reduce monomorphization overhead
5555
fn inner(mut schema: Schema, is_optional: bool) -> Schema {
56-
if is_optional {
57-
schema.remove("required");
58-
}
59-
60-
// Always allow aditional/unevaluated properties, because the outer struct determines
61-
// whether it denies unknown fields.
62-
AllowUnknownProperties::default().transform(&mut schema);
63-
6456
// Special handling for externally-tagged enums with unit variants.
6557
// Unit variants are normally serialized as strings, but when flattened, are serialized
6658
// as objects like `{ "VariantName": null }`
@@ -89,6 +81,37 @@ pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
8981
}
9082
}
9183

84+
if is_optional {
85+
schema.remove("required");
86+
87+
// Handle `Option<>` of externally/internally/adjacently-tagged enums
88+
if let Some(one_of) = schema.remove("oneOf") {
89+
// We can't just add `{}` to the existing `oneOf`, because its items must be
90+
// mutually-exclusive, and `{}` matches everything.
91+
flatten(
92+
&mut schema,
93+
json_schema!({
94+
"anyOf": [
95+
{ "oneOf": one_of },
96+
{}
97+
]
98+
}),
99+
);
100+
}
101+
102+
// Handle `Option<>` of untagged enums
103+
if let Some(Value::Array(any_of)) = schema.get_mut("anyOf") {
104+
let empty_object = Value::Object(Map::new());
105+
if !any_of.contains(&empty_object) {
106+
any_of.push(empty_object);
107+
}
108+
}
109+
}
110+
111+
// Always allow aditional/unevaluated properties, because the outer struct determines
112+
// whether it denies unknown fields.
113+
AllowUnknownProperties::default().transform(&mut schema);
114+
92115
schema
93116
}
94117

0 commit comments

Comments
 (0)