diff --git a/CHANGELOG.md b/CHANGELOG.md index 4033b694..e1c60c51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [0.8.3] - **In-dev** +### Fixed: +- Fix deriving JsonSchema on types defined inside macros (https://github.com/GREsau/schemars/issues/66 / https://github.com/GREsau/schemars/pull/79) + ## [0.8.2] - 2021-03-27 ### Added: - Enable generating a schema from any serializable value using `schema_for_value!(...)` macro or `SchemaGenerator::root_schema_for_value()`/`SchemaGenerator::into_root_schema_for_value()` methods (https://github.com/GREsau/schemars/pull/75) diff --git a/schemars/tests/expected/macro_built_struct.json b/schemars/tests/expected/macro_built_struct.json new file mode 100644 index 00000000..811eae31 --- /dev/null +++ b/schemars/tests/expected/macro_built_struct.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "A", + "type": "object", + "required": [ + "v", + "x" + ], + "properties": { + "x": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "v": { + "type": "integer", + "format": "int32" + } + } +} \ No newline at end of file diff --git a/schemars/tests/macro.rs b/schemars/tests/macro.rs new file mode 100644 index 00000000..0ed39d7c --- /dev/null +++ b/schemars/tests/macro.rs @@ -0,0 +1,22 @@ +mod util; +use schemars::JsonSchema; +use util::*; + +macro_rules! build_struct { + ( + $id:ident { $($t:tt)* } + ) => { + #[derive(Debug, JsonSchema)] + pub struct $id { + x: u8, + $($t)* + } + }; +} + +build_struct!(A { v: i32 }); + +#[test] +fn macro_built_struct() -> TestResult { + test_default_generated_schema::("macro_built_struct") +} diff --git a/schemars_derive/src/schema_exprs.rs b/schemars_derive/src/schema_exprs.rs index a5cf2cac..3b25d050 100644 --- a/schemars_derive/src/schema_exprs.rs +++ b/schemars_derive/src/schema_exprs.rs @@ -390,32 +390,36 @@ fn expr_for_struct( let mut type_defs = Vec::new(); - let properties: Vec<_> = property_fields.into_iter().map(|field| { - let name = field.name(); - let default = field_default_expr(field, set_container_default.is_some()); + let properties: Vec<_> = property_fields + .into_iter() + .map(|field| { + let name = field.name(); + let default = field_default_expr(field, set_container_default.is_some()); - let required = match default { - Some(_) => quote!(false), - None => quote!(true), - }; + let required = match default { + Some(_) => quote!(false), + None => quote!(true), + }; - let metadata = &SchemaMetadata { - read_only: field.serde_attrs.skip_deserializing(), - write_only: field.serde_attrs.skip_serializing(), - default, - ..SchemaMetadata::from_attrs(&field.attrs) - }; + let metadata = &SchemaMetadata { + read_only: field.serde_attrs.skip_deserializing(), + write_only: field.serde_attrs.skip_serializing(), + default, + ..SchemaMetadata::from_attrs(&field.attrs) + }; - let (ty, type_def) = type_for_schema(field, type_defs.len()); - if let Some(type_def) = type_def { - type_defs.push(type_def); - } + let (ty, type_def) = type_for_schema(field, type_defs.len()); + if let Some(type_def) = type_def { + type_defs.push(type_def); + } - quote_spanned! {ty.span()=> - <#ty as schemars::JsonSchema>::add_schema_as_property(gen, &mut schema_object, #name.to_owned(), #metadata, #required); - } + let args = quote!(gen, &mut schema_object, #name.to_owned(), #metadata, #required); - }).collect(); + quote_spanned! {ty.span()=> + <#ty as schemars::JsonSchema>::add_schema_as_property(#args); + } + }) + .collect(); let flattens: Vec<_> = flattened_fields .into_iter()