Add transform = ... attribute (#312)

This allows running arbitrary transforms on generated schemas when deriving `JsonSchema`
This commit is contained in:
Graham Esau 2024-08-10 09:56:52 +01:00 committed by GitHub
parent 29067a0331
commit 14b06e71ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 173 additions and 10 deletions

View file

@ -27,6 +27,7 @@ pub struct Attrs {
pub crate_name: Option<syn::Path>,
pub is_renamed: bool,
pub extensions: Vec<(String, TokenStream)>,
pub transforms: Vec<syn::Expr>,
}
#[derive(Debug)]
@ -70,6 +71,7 @@ impl Attrs {
deprecated: self.deprecated,
examples: &self.examples,
extensions: &self.extensions,
transforms: &self.transforms,
read_only: false,
write_only: false,
default: None,
@ -164,6 +166,25 @@ impl Attrs {
}
}
Meta::NameValue(m) if m.path.is_ident("transform") && attr_type == "schemars" => {
if let syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(lit_str),
..
}) = &m.value
{
if parse_lit_str::<syn::Expr>(lit_str).is_ok() {
errors.error_spanned_by(
&m.value,
format!(
"Expected a `fn(&mut Schema)` or other value implementing `schemars::transform::Transform`, found `&str`.\nDid you mean `[schemars(transform = {})]`?",
lit_str.value()
),
)
}
}
self.transforms.push(m.value.clone());
}
Meta::List(m) if m.path.is_ident("extend") && attr_type == "schemars" => {
let parser =
syn::punctuated::Punctuated::<Extension, Token![,]>::parse_terminated;
@ -224,7 +245,8 @@ impl Attrs {
crate_name: None,
is_renamed: _,
extensions,
} if examples.is_empty() && extensions.is_empty())
transforms
} if examples.is_empty() && extensions.is_empty() && transforms.is_empty())
}
}