Skip to content

Commit

Permalink
Support for #[schemars(crate = "...")] (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
GREsau authored Apr 5, 2021
1 parent ebd7ff3 commit b2b733b
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 11 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# Changelog

## [0.8.3] - **In-dev**
### Added:
- Support for `#[schemars(crate = "...")]` attribute to allow deriving JsonSchema when the schemars crate is aliased to a different name (https://github.com/GREsau/schemars/pull/55 / https://github.com/GREsau/schemars/pull/80)

### Fixed:
- Fix deriving JsonSchema on types defined inside macros (https://github.com/GREsau/schemars/issues/66 / https://github.com/GREsau/schemars/pull/79)
- Fix deriving JsonSchema on types defined inside macros (https://github.com/GREsau/schemars/issues/59 / https://github.com/GREsau/schemars/issues/66 / https://github.com/GREsau/schemars/pull/79)

## [0.8.2] - 2021-03-27
### Added:
Expand Down
10 changes: 10 additions & 0 deletions docs/1.1-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ Set on a container, variant or field to include the result of the given function

Set the Rust built-in [`deprecated`](https://doc.rust-lang.org/edition-guide/rust-2018/the-compiler/an-attribute-for-deprecation.html) attribute on a struct, enum, field or variant to set the generated schema's `deprecated` keyword to `true`.

<!--
TODO Uncomment for 0.8.3
<h3 id="crate">
`#[schemars(crate = "other_crate::schemars")]`
</h3>
Set the path to the schemars crate instance the generated code should depend on. This is mostly useful for other crates that depend on schemars in their macros.
-->

<h3 id="doc">

Doc Comments (`#[doc = "..."]`)
Expand Down
19 changes: 19 additions & 0 deletions schemars/tests/crate_alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
mod util;
use ::schemars as not_schemars;
use util::*;

#[allow(unused_imports)]
use std as schemars;

#[derive(Debug, not_schemars::JsonSchema)]
#[schemars(crate = "not_schemars")]
pub struct Struct {
/// This is a document
foo: i32,
bar: bool,
}

#[test]
fn test_crate_alias() -> TestResult {
test_default_generated_schema::<Struct>("crate_alias")
}
19 changes: 19 additions & 0 deletions schemars/tests/expected/crate_alias.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Struct",
"type": "object",
"required": [
"bar",
"foo"
],
"properties": {
"foo": {
"description": "This is a document",
"type": "integer",
"format": "int32"
},
"bar": {
"type": "boolean"
}
}
}
15 changes: 15 additions & 0 deletions schemars_derive/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ use syn::Meta::{List, NameValue};
use syn::MetaNameValue;
use syn::NestedMeta::{Lit, Meta};

// FIXME using the same struct for containers+variants+fields means that
// with/schema_with are accepted (but ignored) on containers, and
// repr/crate_name are accepted (but ignored) on variants and fields etc.

#[derive(Debug, Default)]
pub struct Attrs {
pub with: Option<WithAttr>,
Expand All @@ -19,6 +23,7 @@ pub struct Attrs {
pub deprecated: bool,
pub examples: Vec<syn::Path>,
pub repr: Option<syn::Type>,
pub crate_name: Option<syn::Path>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -123,6 +128,16 @@ impl Attrs {
}
}

Meta(NameValue(m)) if m.path.is_ident("crate") => {
if let Ok(p) = parse_lit_into_path(errors, attr_type, "crate", &m.lit) {
if self.crate_name.is_some() {
duplicate_error(m)
} else {
self.crate_name = Some(p)
}
}
}

_ if ignore_errors => {}

Meta(meta_item) => {
Expand Down
31 changes: 21 additions & 10 deletions schemars_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod schema_exprs;

use ast::*;
use proc_macro2::TokenStream;
use syn::spanned::Spanned;

#[proc_macro_derive(JsonSchema, attributes(schemars, serde))]
pub fn derive_json_schema_wrapper(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand All @@ -39,6 +40,11 @@ fn derive_json_schema(
attr::process_serde_attrs(&mut input)?;

let cont = Container::from_ast(&input)?;
let crate_alias = cont.attrs.crate_name.as_ref().map(|path| {
quote_spanned! {path.span()=>
use #path as schemars;
}
});

let type_name = &cont.ident;
let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();
Expand All @@ -47,6 +53,7 @@ fn derive_json_schema(
let (ty, type_def) = schema_exprs::type_for_schema(transparent_field, 0);
return Ok(quote! {
const _: () = {
#crate_alias
#type_def

#[automatically_derived]
Expand Down Expand Up @@ -121,16 +128,20 @@ fn derive_json_schema(
};

Ok(quote! {
#[automatically_derived]
#[allow(unused_braces)]
impl #impl_generics schemars::JsonSchema for #type_name #ty_generics #where_clause {
fn schema_name() -> std::string::String {
#schema_name
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
#schema_expr
}
const _: () = {
#crate_alias

#[automatically_derived]
#[allow(unused_braces)]
impl #impl_generics schemars::JsonSchema for #type_name #ty_generics #where_clause {
fn schema_name() -> std::string::String {
#schema_name
}

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
#schema_expr
}
};
};
})
}
Expand Down

0 comments on commit b2b733b

Please sign in to comment.