Fix skip_serializing_if/serialize_with handling
Previously whenever a field with a default value has both `skip_serializing_if` and `with`/`serialize_with` attributes, the value would be converted to a type that performs the custom serialization before checking if it should be serialized. This would cause the wrong type to be given to the skip_serializing_if function, causing a compile error. Issue #26
This commit is contained in:
parent
d1f2c0f803
commit
63af0ceb73
7 changed files with 54 additions and 42 deletions
|
@ -343,12 +343,22 @@ impl SchemaGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn apply_metadata(&self, schema: Schema, metadata: Metadata) -> Schema {
|
||||
let mut schema_obj = schema.into();
|
||||
/// This function is only public for use by schemars_derive.
|
||||
///
|
||||
/// It should not be considered part of the public API.
|
||||
#[doc(hidden)]
|
||||
pub fn apply_metadata(&self, schema: Schema, metadata: Option<Metadata>) -> Schema {
|
||||
match metadata {
|
||||
None => return schema,
|
||||
Some(metadata) if metadata == Metadata::default() => return schema,
|
||||
Some(metadata) => {
|
||||
let mut schema_obj = schema.into();
|
||||
|
||||
self.make_extensible(&mut schema_obj);
|
||||
schema_obj.metadata = Some(Box::new(metadata)).merge(schema_obj.metadata);
|
||||
self.make_extensible(&mut schema_obj);
|
||||
schema_obj.metadata = Some(Box::new(metadata)).merge(schema_obj.metadata);
|
||||
|
||||
Schema::Object(schema_obj)
|
||||
Schema::Object(schema_obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,10 +65,7 @@ impl<T: JsonSchema> JsonSchema for Option<T> {
|
|||
_required: bool,
|
||||
) {
|
||||
let mut schema = gen.subschema_for::<Self>();
|
||||
|
||||
if let Some(metadata) = metadata {
|
||||
schema = gen.apply_metadata(schema, metadata);
|
||||
}
|
||||
schema = gen.apply_metadata(schema, metadata);
|
||||
|
||||
let object = parent.object();
|
||||
object.properties.insert(name, schema);
|
||||
|
|
|
@ -300,10 +300,7 @@ pub trait JsonSchema {
|
|||
required: bool,
|
||||
) {
|
||||
let mut schema = gen.subschema_for::<Self>();
|
||||
|
||||
if let Some(metadata) = metadata {
|
||||
schema = gen.apply_metadata(schema, metadata);
|
||||
}
|
||||
schema = gen.apply_metadata(schema, metadata);
|
||||
|
||||
let object = parent.object();
|
||||
if required {
|
||||
|
|
|
@ -3,6 +3,10 @@ use schemars::JsonSchema;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use util::*;
|
||||
|
||||
fn is_default<T: Default + PartialEq>(value: &T) -> bool {
|
||||
value == &T::default()
|
||||
}
|
||||
|
||||
fn ten_and_true() -> MyStruct2 {
|
||||
MyStruct2 {
|
||||
my_int: 10,
|
||||
|
@ -28,9 +32,14 @@ pub struct MyStruct {
|
|||
pub my_bool: bool,
|
||||
#[serde(serialize_with = "custom_serialize")]
|
||||
pub my_struct2: MyStruct2,
|
||||
#[serde(
|
||||
serialize_with = "custom_serialize",
|
||||
skip_serializing_if = "is_default"
|
||||
)]
|
||||
pub my_struct2_default_skipped: MyStruct2,
|
||||
}
|
||||
|
||||
#[derive(Default, Deserialize, Serialize, JsonSchema, Debug)]
|
||||
#[derive(Default, Deserialize, Serialize, JsonSchema, Debug, PartialEq)]
|
||||
#[serde(default = "ten_and_true")]
|
||||
pub struct MyStruct2 {
|
||||
#[serde(default = "six")]
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
"$ref": "#/definitions/MyStruct2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"my_struct2_default_skipped": {
|
||||
"$ref": "#/definitions/MyStruct2"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue