struct_patch_derive/
lib.rs1extern 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}