sabry_procmacro_impl/impls/
usey.rs1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::{parse::Parse, punctuated::Punctuated, Macro, Token};
4
5pub fn usey_macro_impl(input: TokenStream) -> TokenStream {
8 let MacroSyntax { stylecalls } = match syn::parse2(input) {
9 Ok(ms) => ms,
10 Err(e) => return e.to_compile_error(),
11 };
12
13 let stylecall_pairs = stylecalls
14 .iter()
15 .map(|c| c.to_contract_pair("__sabry_pub_module"));
16
17 quote! {
18 vec![
19 #(#stylecall_pairs,)*
20 ]
21 }
22}
23
24#[derive(Clone)]
25pub struct StyleCall {
26 vis_pub: bool,
27 call: Macro,
28}
29
30impl StyleCall {
31 pub fn to_contract_pair(&self, pub_module: &str) -> TokenStream {
32 let call_code = &self.call;
33 let call_path = &self.call.path;
34 let call_bang = &self.call.bang_token;
35 let call_syntax = quote! {#call_path #call_bang (syntax)};
37
38 let module_name = call_path
39 .segments
40 .last()
41 .map(|l| l.ident.to_string())
42 .expect("BUG: failed to get identifier for macro call");
43
44 if self.vis_pub {
45 quote! {
46 (format!("{}.{}", #pub_module, #call_syntax), #call_code .to_string())
47 }
48 } else {
49 quote! {
50 (format!("{}.{}", #module_name, #call_syntax), #call_code .to_string())
51 }
52 }
53 }
54}
55
56impl Parse for StyleCall {
57 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
58 let vis_pub = input.parse::<Token![pub]>().is_ok();
59 let call = input.parse::<Macro>()?;
60
61 Ok(Self { vis_pub, call })
62 }
63}
64
65pub struct MacroSyntax {
66 stylecalls: Vec<StyleCall>,
67}
68
69impl Parse for MacroSyntax {
70 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
71 let calls = Punctuated::<StyleCall, Token![,]>::parse_separated_nonempty(input)?;
72
73 let stylecalls = calls.iter().cloned().collect();
74 Ok(Self { stylecalls })
75 }
76}