Use const
instead of single-valued enum
(#291)
This commit is contained in:
parent
8c2c32bce0
commit
18300c67bb
14 changed files with 61 additions and 131 deletions
|
@ -53,17 +53,16 @@ impl<T: Serialize> MaybeSerializeWrapper<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a schema for a unit enum
|
||||
pub fn new_unit_enum(variant: &str) -> Schema {
|
||||
// TODO switch from single-valued "enum" to "const"
|
||||
/// Create a schema for a unit enum variant
|
||||
pub fn new_unit_enum_variant(variant: &str) -> Schema {
|
||||
json_schema!({
|
||||
"type": "string",
|
||||
"enum": [variant],
|
||||
"const": variant,
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a schema for an externally tagged enum
|
||||
pub fn new_externally_tagged_enum(variant: &str, sub_schema: Schema) -> Schema {
|
||||
/// Create a schema for an externally tagged enum variant
|
||||
pub fn new_externally_tagged_enum_variant(variant: &str, sub_schema: Schema) -> Schema {
|
||||
json_schema!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -74,7 +73,8 @@ pub fn new_externally_tagged_enum(variant: &str, sub_schema: Schema) -> Schema {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn apply_internal_enum_tag(
|
||||
/// Update a schema for an internally tagged enum variant
|
||||
pub fn apply_internal_enum_variant_tag(
|
||||
schema: &mut Schema,
|
||||
tag_name: &str,
|
||||
variant: &str,
|
||||
|
@ -94,8 +94,7 @@ pub fn apply_internal_enum_tag(
|
|||
tag_name.to_string(),
|
||||
json!({
|
||||
"type": "string",
|
||||
// TODO switch from single-valued "enum" to "const"
|
||||
"enum": [variant]
|
||||
"const": variant
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -113,34 +112,6 @@ pub fn apply_internal_enum_tag(
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a schema for an internally tagged enum
|
||||
pub fn new_internally_tagged_enum(
|
||||
tag_name: &str,
|
||||
variant: &str,
|
||||
deny_unknown_fields: bool,
|
||||
) -> Schema {
|
||||
// TODO switch from single-valued "enum" to "const"
|
||||
let mut schema = json_schema!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
tag_name: {
|
||||
"type": "string",
|
||||
"enum": [variant],
|
||||
}
|
||||
},
|
||||
"required": [tag_name],
|
||||
});
|
||||
|
||||
if deny_unknown_fields {
|
||||
schema
|
||||
.as_object_mut()
|
||||
.unwrap()
|
||||
.insert("additionalProperties".into(), false.into());
|
||||
}
|
||||
|
||||
schema
|
||||
}
|
||||
|
||||
pub fn insert_object_property<T: ?Sized + JsonSchema>(
|
||||
schema: &mut Schema,
|
||||
key: &str,
|
||||
|
|
|
@ -97,6 +97,7 @@ impl SchemaSettings {
|
|||
skip_additional_properties: true,
|
||||
}),
|
||||
Box::new(SetSingleExample),
|
||||
Box::new(ReplaceConstValue),
|
||||
],
|
||||
inline_subschemas: false,
|
||||
}
|
||||
|
|
|
@ -169,3 +169,21 @@ impl Visitor for SetSingleExample {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This visitor will replace the `const` schema property with a single-valued `enum` property.
|
||||
///
|
||||
/// This is useful for dialects of JSON Schema (e.g. OpenAPI 3.0) that do not support the `const` property.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReplaceConstValue;
|
||||
|
||||
impl Visitor for ReplaceConstValue {
|
||||
fn visit_schema(&mut self, schema: &mut Schema) {
|
||||
visit_schema(self, schema);
|
||||
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if let Some(value) = obj.remove("const") {
|
||||
obj.insert("enum".into(), Value::Array(vec![value]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,8 @@
|
|||
},
|
||||
{
|
||||
"type": "string",
|
||||
"deprecated": true,
|
||||
"enum": [
|
||||
"DeprecatedUnitVariant"
|
||||
]
|
||||
"const": "DeprecatedUnitVariant",
|
||||
"deprecated": true
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
{
|
||||
"description": "This comment is included in the generated schema :)",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DocumentedUnit"
|
||||
]
|
||||
"const": "DocumentedUnit"
|
||||
},
|
||||
{
|
||||
"title": "Complex variant",
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitOne"
|
||||
]
|
||||
"const": "UnitOne"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -22,9 +20,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"StringMap"
|
||||
]
|
||||
"const": "StringMap"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {
|
||||
|
@ -39,9 +35,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitStructNewType"
|
||||
]
|
||||
"const": "UnitStructNewType"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -61,9 +55,7 @@
|
|||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"StructNewType"
|
||||
]
|
||||
"const": "StructNewType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -84,9 +76,7 @@
|
|||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Struct"
|
||||
]
|
||||
"const": "Struct"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -101,9 +91,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitTwo"
|
||||
]
|
||||
"const": "UnitTwo"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -117,9 +105,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"WithInt"
|
||||
]
|
||||
"const": "WithInt"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitOne"
|
||||
]
|
||||
"const": "UnitOne"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -21,9 +19,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"StringMap"
|
||||
]
|
||||
"const": "StringMap"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {
|
||||
|
@ -38,9 +34,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitStructNewType"
|
||||
]
|
||||
"const": "UnitStructNewType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -59,9 +53,7 @@
|
|||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"StructNewType"
|
||||
]
|
||||
"const": "StructNewType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -82,9 +74,7 @@
|
|||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Struct"
|
||||
]
|
||||
"const": "Struct"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -98,9 +88,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"UnitTwo"
|
||||
]
|
||||
"const": "UnitTwo"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -113,9 +101,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"WithInt"
|
||||
]
|
||||
"const": "WithInt"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"A"
|
||||
]
|
||||
"const": "A"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -22,9 +20,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"B"
|
||||
]
|
||||
"const": "B"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
@ -37,9 +33,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"C"
|
||||
]
|
||||
"const": "C"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"A"
|
||||
]
|
||||
"const": "A"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -21,9 +19,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"B"
|
||||
]
|
||||
"const": "B"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -35,9 +31,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"C"
|
||||
]
|
||||
"const": "C"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -6,23 +6,17 @@
|
|||
"title": "A deer",
|
||||
"description": "A female deer",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Do"
|
||||
]
|
||||
"const": "Do"
|
||||
},
|
||||
{
|
||||
"description": "A drop of golden sun",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Re"
|
||||
]
|
||||
"const": "Re"
|
||||
},
|
||||
{
|
||||
"description": "A name I call myself",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Mi"
|
||||
]
|
||||
"const": "Mi"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -45,9 +45,7 @@
|
|||
{
|
||||
"description": "This is a documented unit variant",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DocumentedUnit"
|
||||
]
|
||||
"const": "DocumentedUnit"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
|
|
|
@ -45,9 +45,7 @@
|
|||
{
|
||||
"description": "This is a documented unit variant",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DocumentedUnit"
|
||||
]
|
||||
"const": "DocumentedUnit"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
},
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Struct"
|
||||
]
|
||||
"const": "Struct"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -25,9 +23,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NewType"
|
||||
]
|
||||
"const": "NewType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -39,9 +35,7 @@
|
|||
"properties": {
|
||||
"typeProperty": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Unit"
|
||||
]
|
||||
"const": "Unit"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
|
|
@ -197,12 +197,12 @@ fn expr_for_external_tagged_enum<'a>(
|
|||
|
||||
let mut schema_expr = if variant.is_unit() && variant.attrs.with.is_none() {
|
||||
quote! {
|
||||
schemars::_private::new_unit_enum(#name)
|
||||
schemars::_private::new_unit_enum_variant(#name)
|
||||
}
|
||||
} else {
|
||||
let sub_schema = expr_for_untagged_enum_variant(variant, deny_unknown_fields);
|
||||
quote! {
|
||||
schemars::_private::new_externally_tagged_enum(#name, #sub_schema)
|
||||
schemars::_private::new_externally_tagged_enum_variant(#name, #sub_schema)
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -236,7 +236,7 @@ fn expr_for_internal_tagged_enum<'a>(
|
|||
|
||||
quote!({
|
||||
let mut schema = #schema_expr;
|
||||
schemars::_private::apply_internal_enum_tag(&mut schema, #tag_name, #name, #deny_unknown_fields);
|
||||
schemars::_private::apply_internal_enum_variant_tag(&mut schema, #tag_name, #name, #deny_unknown_fields);
|
||||
schema
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue