Skip to main content

struct_patch_derive/
lib.rs

1extern crate proc_macro;
2#[cfg(feature = "catalyst")]
3mod catalyst;
4mod filler;
5mod patch;
6#[cfg(feature = "catalyst")]
7mod substrate;
8
9#[cfg(feature = "catalyst")]
10use catalyst::Catalyst;
11use filler::Filler;
12use patch::Patch;
13#[cfg(feature = "catalyst")]
14use substrate::Substrate;
15
16use syn::meta::ParseNestedMeta;
17use syn::spanned::Spanned;
18use syn::Error;
19
20#[cfg(feature = "op")]
21pub(crate) enum Addable {
22    Disable,
23    AddTrait,
24    AddFn(proc_macro2::Ident),
25}
26
27#[proc_macro_derive(Patch, attributes(patch))]
28pub fn derive_patch(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
29    Patch::from_ast(syn::parse_macro_input!(item as syn::DeriveInput))
30        .unwrap()
31        .to_token_stream()
32        .unwrap()
33        .into()
34}
35
36#[proc_macro_derive(Filler, attributes(filler))]
37pub fn derive_filler(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
38    Filler::from_ast(syn::parse_macro_input!(item as syn::DeriveInput))
39        .unwrap()
40        .to_token_stream()
41        .unwrap()
42        .into()
43}
44
45#[cfg(feature = "catalyst")]
46#[proc_macro_derive(Substrate, attributes(substrate))]
47pub fn derive_substrate(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
48    Substrate::from_ast(syn::parse_macro_input!(item as syn::DeriveInput))
49        .unwrap()
50        .to_token_stream()
51        .unwrap()
52        .into()
53}
54
55#[cfg(feature = "catalyst")]
56#[proc_macro_derive(Catalyst, attributes(catalyst, complex))]
57pub fn derive_catalyst(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
58    Catalyst::from_ast(syn::parse_macro_input!(item as syn::DeriveInput))
59        .unwrap()
60        .to_token_stream()
61        .unwrap()
62        .into()
63}
64
65fn get_lit(attr_name: String, meta: &ParseNestedMeta) -> syn::Result<Option<syn::Lit>> {
66    let expr: syn::Expr = meta.value()?.parse()?;
67    let mut value = &expr;
68    while let syn::Expr::Group(e) = value {
69        value = &e.expr;
70    }
71    if let syn::Expr::Lit(syn::ExprLit { lit, .. }) = value {
72        Ok(Some(lit.clone()))
73    } else {
74        Err(Error::new(
75            expr.span(),
76            format!(
77                "expected serde {} attribute to be lit: `{} = \"...\"`",
78                attr_name, attr_name
79            ),
80        ))
81    }
82}
83
84fn get_lit_str(attr_name: String, meta: &ParseNestedMeta) -> syn::Result<Option<syn::LitStr>> {
85    let expr: syn::Expr = meta.value()?.parse()?;
86    let mut value = &expr;
87    while let syn::Expr::Group(e) = value {
88        value = &e.expr;
89    }
90    if let syn::Expr::Lit(syn::ExprLit {
91        lit: syn::Lit::Str(lit),
92        ..
93    }) = value
94    {
95        let suffix = lit.suffix();
96        if !suffix.is_empty() {
97            return Err(Error::new(
98                lit.span(),
99                format!("unexpected suffix `{}` on string literal", suffix),
100            ));
101        }
102        Ok(Some(lit.clone()))
103    } else {
104        Err(Error::new(
105            expr.span(),
106            format!(
107                "expected serde {} attribute to be a string: `{} = \"...\"`",
108                attr_name, attr_name
109            ),
110        ))
111    }
112}