Derive JsonSchema_repr (#76)

This commit is contained in:
Graham Esau 2021-03-25 22:36:28 +00:00 committed by GitHub
parent 7de2b2276f
commit 11d95b79e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 225 additions and 18 deletions

View file

@ -1,5 +1,5 @@
use crate::{ast::*, attr::WithAttr, metadata::SchemaMetadata};
use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use serde_derive_internals::ast::Style;
use serde_derive_internals::attr::{self as serde_attr, Default as SerdeDefault, TagType};
use syn::spanned::Spanned;
@ -21,6 +21,41 @@ pub fn expr_for_container(cont: &Container) -> TokenStream {
doc_metadata.apply_to_schema(schema_expr)
}
pub fn expr_for_repr(cont: &Container) -> Result<TokenStream, syn::Error> {
let repr_type = cont.attrs.repr.as_ref().ok_or_else(|| {
syn::Error::new(
Span::call_site(),
"JsonSchema_repr: missing #[repr(...)] attribute",
)
})?;
let variants = match &cont.data {
Data::Enum(variants) => variants,
_ => return Err(syn::Error::new(Span::call_site(), "oh no!")),
};
if let Some(non_unit_error) = variants.iter().find_map(|v| match v.style {
Style::Unit => None,
_ => Some(syn::Error::new(
v.original.span(),
"JsonSchema_repr: must be a unit variant",
)),
}) {
return Err(non_unit_error);
};
let enum_ident = &cont.ident;
let variant_idents = variants.iter().map(|v| &v.ident);
let schema_expr = schema_object(quote! {
instance_type: Some(schemars::schema::InstanceType::Integer.into()),
enum_values: Some(vec![#((#enum_ident::#variant_idents as #repr_type).into()),*]),
});
let doc_metadata = SchemaMetadata::from_attrs(&cont.attrs);
Ok(doc_metadata.apply_to_schema(schema_expr))
}
fn expr_for_field(field: &Field, allow_ref: bool) -> TokenStream {
let (ty, type_def) = type_for_schema(field, 0);
let span = field.original.span();
@ -300,7 +335,7 @@ fn expr_for_untagged_enum_variant_for_flatten(
) -> Option<TokenStream> {
if let Some(WithAttr::Type(with)) = &variant.attrs.with {
return Some(quote_spanned! {variant.original.span()=>
<#with>::json_schema(gen)
<#with as schemars::JsonSchema>::json_schema(gen)
});
}