1mod config;
2mod r#gen;
3mod value;
4
5use quote::quote;
6use r#gen::CoteGenerator;
7use r#gen::FetchGenerator;
8use r#gen::InferGenerator;
9use r#gen::ValueGenerator;
10use syn::parse_macro_input;
11use syn::spanned::Spanned;
12use syn::DataEnum;
13use syn::DeriveInput;
14
15fn error(spanned: impl Spanned, msg: impl Into<String>) -> syn::Error {
16 syn::Error::new(spanned.span(), msg.into())
17}
18
19#[proc_macro_derive(Cote, attributes(cote, arg, pos, cmd, sub))]
20pub fn parser(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
21 let input: DeriveInput = parse_macro_input!(input);
22 let generator = |input: DeriveInput| -> syn::Result<proc_macro2::TokenStream> {
23 let mut cg = CoteGenerator::new(&input)?;
24
25 cg.gen_impl_for_struct()
26 };
27
28 let ts = generator(input).unwrap_or_else(syn::Error::into_compile_error);
29
30 quote! {
31 #ts
32 }
33 .into()
34}
35
36#[proc_macro_derive(CoteOpt, attributes(infer, fetch))]
37pub fn parser_opt(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
38 let input: DeriveInput = parse_macro_input!(input);
39 let generator = |input| -> syn::Result<proc_macro2::TokenStream> {
40 let fg = FetchGenerator::new(input)?;
41 let ig = InferGenerator::new(input)?;
42 let fg = fg.gen_impl_for_struct()?;
43 let ig = ig.gen_impl_for_struct()?;
44
45 Ok(quote::quote! { #fg #ig })
46 };
47
48 generator(&input)
49 .unwrap_or_else(syn::Error::into_compile_error)
50 .into()
51}
52
53#[proc_macro_derive(CoteVal, attributes(coteval))]
54pub fn parser_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
55 let input: DeriveInput = parse_macro_input!(input);
56 let generator = |input, variants| ValueGenerator::new(input, variants)?.gen_impl_for_enum();
57 let ts = generator(
58 &input,
59 if let syn::Data::Enum(DataEnum { ref variants, .. }) = &input.data {
60 Some(variants)
61 } else {
62 None
63 },
64 )
65 .unwrap_or_else(syn::Error::into_compile_error);
66
67 ts.into()
68}