saa_proto_core/
utils.rs

1use std::fmt::Display;
2use quote::ToTokens;
3use syn::{
4    parse::{Parse, ParseStream}, parse_quote, punctuated::Punctuated, Lit, Meta, Token
5};
6
7
8macro_rules! fallible_macro {
9    (
10        $(
11            #[ $( $attribute_decl:tt )* ]
12        )*
13        pub fn $macro_name:ident ( $( $params:tt )* ) -> syn::Result<$inner_return:path> {
14            $( $fn_body:tt )*
15        }
16    ) => {
17        $(
18            #[ $( $attribute_decl )* ]
19        )*
20        pub fn $macro_name ( $( $params )* ) -> $inner_return {
21            let result = move || -> ::syn::Result<_> {
22                $( $fn_body )*
23            };
24
25            match result() {
26                Ok(val) => val,
27                Err(err) => err.into_compile_error().into(),
28            }
29        }
30    }
31}
32
33
34#[derive(Debug, Clone)]
35pub struct Options {
36    pub crate_path: syn::Path,
37}
38
39impl Default for Options {
40    fn default() -> Self {
41        Self {
42            crate_path: parse_quote!(::saa_schema),
43        }
44    }
45}
46
47impl Display for Options {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        write!(f, "crate_path: {}", self.crate_path.to_token_stream())
50    }
51}
52
53
54impl Parse for Options {
55    fn parse(input: ParseStream) -> syn::Result<Self> {
56        let mut acc = Self::default();
57        let params = Punctuated::<Meta, Token![,]>::parse_terminated(input)?;
58        for param in params {
59            match param {
60                Meta::NameValue(nv) => {
61                    if nv.path.is_ident("crate") {
62                        if let Lit::Str(s) = nv.lit {
63                            acc.crate_path = s.parse()?;
64                        } else {
65                            return Err(syn::Error::new_spanned(nv.lit, "expected string literal"));
66                        }
67                    } else {
68                        return Err(syn::Error::new_spanned(nv.path, "unknown option"));
69                    }
70                }
71                _ => {
72                    return Err(syn::Error::new_spanned(param, "expected `key = \"value\"` format"));
73                }
74            }
75        }
76        Ok(acc)
77    }
78}
79
80pub(crate) use fallible_macro;