Add schema_id(), handles different types with the same name (#247)

This commit is contained in:
Graham Esau 2023-09-17 20:36:52 +01:00 committed by GitHub
parent 53bb51cb25
commit 342b2dff33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 415 additions and 34 deletions

View file

@ -67,6 +67,10 @@ fn derive_json_schema(
<#ty as schemars::JsonSchema>::schema_name()
}
fn schema_id() -> std::borrow::Cow<'static, str> {
<#ty as schemars::JsonSchema>::schema_id()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<#ty as schemars::JsonSchema>::json_schema(gen)
}
@ -98,27 +102,66 @@ fn derive_json_schema(
let const_params: Vec<_> = cont.generics.const_params().map(|c| &c.ident).collect();
let params: Vec<_> = type_params.iter().chain(const_params.iter()).collect();
let schema_name = if params.is_empty()
let (schema_name, schema_id) = if params.is_empty()
|| (cont.attrs.is_renamed && !schema_base_name.contains('{'))
{
quote! {
#schema_base_name.to_owned()
}
(
quote! {
#schema_base_name.to_owned()
},
quote! {
std::borrow::Cow::Borrowed(std::concat!(
std::module_path!(),
"::",
#schema_base_name
))
},
)
} else if cont.attrs.is_renamed {
let mut schema_name_fmt = schema_base_name;
for tp in &params {
schema_name_fmt.push_str(&format!("{{{}:.0}}", tp));
}
quote! {
format!(#schema_name_fmt #(,#type_params=#type_params::schema_name())* #(,#const_params=#const_params)*)
}
(
quote! {
format!(#schema_name_fmt #(,#type_params=#type_params::schema_name())* #(,#const_params=#const_params)*)
},
quote! {
std::borrow::Cow::Owned(
format!(
std::concat!(
std::module_path!(),
"::",
#schema_name_fmt
)
#(,#type_params=#type_params::schema_id())*
#(,#const_params=#const_params)*
)
)
},
)
} else {
let mut schema_name_fmt = schema_base_name;
schema_name_fmt.push_str("_for_{}");
schema_name_fmt.push_str(&"_and_{}".repeat(params.len() - 1));
quote! {
format!(#schema_name_fmt #(,#type_params::schema_name())* #(,#const_params)*)
}
(
quote! {
format!(#schema_name_fmt #(,#type_params::schema_name())* #(,#const_params)*)
},
quote! {
std::borrow::Cow::Owned(
format!(
std::concat!(
std::module_path!(),
"::",
#schema_name_fmt
)
#(,#type_params::schema_id())*
#(,#const_params)*
)
)
},
)
};
let schema_expr = if repr {
@ -138,6 +181,10 @@ fn derive_json_schema(
#schema_name
}
fn schema_id() -> std::borrow::Cow<'static, str> {
#schema_id
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
#schema_expr
}

View file

@ -109,6 +109,15 @@ fn type_for_schema(with_attr: &WithAttr) -> (syn::Type, Option<TokenStream>) {
#fn_name.to_string()
}
fn schema_id() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed(std::concat!(
"_SchemarsSchemaWithFunction/",
std::module_path!(),
"/",
#fn_name
))
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
#fun(gen)
}