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
|
/// Create a schema for a unit enum variant
|
||||||
pub fn new_unit_enum(variant: &str) -> Schema {
|
pub fn new_unit_enum_variant(variant: &str) -> Schema {
|
||||||
// TODO switch from single-valued "enum" to "const"
|
|
||||||
json_schema!({
|
json_schema!({
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [variant],
|
"const": variant,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a schema for an externally tagged enum
|
/// Create a schema for an externally tagged enum variant
|
||||||
pub fn new_externally_tagged_enum(variant: &str, sub_schema: Schema) -> Schema {
|
pub fn new_externally_tagged_enum_variant(variant: &str, sub_schema: Schema) -> Schema {
|
||||||
json_schema!({
|
json_schema!({
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"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,
|
schema: &mut Schema,
|
||||||
tag_name: &str,
|
tag_name: &str,
|
||||||
variant: &str,
|
variant: &str,
|
||||||
|
@ -94,8 +94,7 @@ pub fn apply_internal_enum_tag(
|
||||||
tag_name.to_string(),
|
tag_name.to_string(),
|
||||||
json!({
|
json!({
|
||||||
"type": "string",
|
"type": "string",
|
||||||
// TODO switch from single-valued "enum" to "const"
|
"const": variant
|
||||||
"enum": [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>(
|
pub fn insert_object_property<T: ?Sized + JsonSchema>(
|
||||||
schema: &mut Schema,
|
schema: &mut Schema,
|
||||||
key: &str,
|
key: &str,
|
||||||
|
|
|
@ -97,6 +97,7 @@ impl SchemaSettings {
|
||||||
skip_additional_properties: true,
|
skip_additional_properties: true,
|
||||||
}),
|
}),
|
||||||
Box::new(SetSingleExample),
|
Box::new(SetSingleExample),
|
||||||
|
Box::new(ReplaceConstValue),
|
||||||
],
|
],
|
||||||
inline_subschemas: false,
|
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",
|
"type": "string",
|
||||||
"deprecated": true,
|
"const": "DeprecatedUnitVariant",
|
||||||
"enum": [
|
"deprecated": true
|
||||||
"DeprecatedUnitVariant"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -13,9 +13,7 @@
|
||||||
{
|
{
|
||||||
"description": "This comment is included in the generated schema :)",
|
"description": "This comment is included in the generated schema :)",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "DocumentedUnit"
|
||||||
"DocumentedUnit"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Complex variant",
|
"title": "Complex variant",
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitOne"
|
||||||
"UnitOne"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -22,9 +20,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "StringMap"
|
||||||
"StringMap"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
|
@ -39,9 +35,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitStructNewType"
|
||||||
"UnitStructNewType"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -61,9 +55,7 @@
|
||||||
},
|
},
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "StructNewType"
|
||||||
"StructNewType"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -84,9 +76,7 @@
|
||||||
},
|
},
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Struct"
|
||||||
"Struct"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -101,9 +91,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitTwo"
|
||||||
"UnitTwo"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -117,9 +105,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "WithInt"
|
||||||
"WithInt"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitOne"
|
||||||
"UnitOne"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -21,9 +19,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "StringMap"
|
||||||
"StringMap"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
|
@ -38,9 +34,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitStructNewType"
|
||||||
"UnitStructNewType"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -59,9 +53,7 @@
|
||||||
},
|
},
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "StructNewType"
|
||||||
"StructNewType"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -82,9 +74,7 @@
|
||||||
},
|
},
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Struct"
|
||||||
"Struct"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -98,9 +88,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "UnitTwo"
|
||||||
"UnitTwo"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -113,9 +101,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "WithInt"
|
||||||
"WithInt"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "A"
|
||||||
"A"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -22,9 +20,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "B"
|
||||||
"B"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
@ -37,9 +33,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "C"
|
||||||
"C"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "A"
|
||||||
"A"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -21,9 +19,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "B"
|
||||||
"B"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -35,9 +31,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "C"
|
||||||
"C"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|
|
@ -6,23 +6,17 @@
|
||||||
"title": "A deer",
|
"title": "A deer",
|
||||||
"description": "A female deer",
|
"description": "A female deer",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Do"
|
||||||
"Do"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "A drop of golden sun",
|
"description": "A drop of golden sun",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Re"
|
||||||
"Re"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "A name I call myself",
|
"description": "A name I call myself",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Mi"
|
||||||
"Mi"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -45,9 +45,7 @@
|
||||||
{
|
{
|
||||||
"description": "This is a documented unit variant",
|
"description": "This is a documented unit variant",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "DocumentedUnit"
|
||||||
"DocumentedUnit"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -45,9 +45,7 @@
|
||||||
{
|
{
|
||||||
"description": "This is a documented unit variant",
|
"description": "This is a documented unit variant",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "DocumentedUnit"
|
||||||
"DocumentedUnit"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -10,9 +10,7 @@
|
||||||
},
|
},
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Struct"
|
||||||
"Struct"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -25,9 +23,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "NewType"
|
||||||
"NewType"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -39,9 +35,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"typeProperty": {
|
"typeProperty": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"const": "Unit"
|
||||||
"Unit"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"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() {
|
let mut schema_expr = if variant.is_unit() && variant.attrs.with.is_none() {
|
||||||
quote! {
|
quote! {
|
||||||
schemars::_private::new_unit_enum(#name)
|
schemars::_private::new_unit_enum_variant(#name)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let sub_schema = expr_for_untagged_enum_variant(variant, deny_unknown_fields);
|
let sub_schema = expr_for_untagged_enum_variant(variant, deny_unknown_fields);
|
||||||
quote! {
|
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!({
|
quote!({
|
||||||
let mut schema = #schema_expr;
|
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
|
schema
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue