writings_macros/
lib.rs

1//! Procedural macros for the [writings](../writings) crate.
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{Data, DataEnum, DeriveInput, parse_macro_input};
6
7#[proc_macro_derive(WritingsTrait)]
8pub fn derive_writings_trait(input: TokenStream) -> TokenStream {
9    let input = parse_macro_input!(input as DeriveInput);
10    let name = &input.ident;
11
12    let variants = match &input.data {
13        Data::Enum(DataEnum { variants, .. }) => variants,
14        _ => panic!("WritingsTrait can only be derived for enums"),
15    };
16
17    let match_arms: Vec<_> = variants
18        .iter()
19        .map(|v| {
20            let variant_name = &v.ident;
21            quote! {
22                #name::#variant_name(item) => item
23            }
24        })
25        .collect();
26
27    let expanded = quote! {
28        impl WritingsTrait for #name {
29            fn ref_id(&self) -> String {
30                match self {
31                    #(#match_arms.ref_id(),)*
32                }
33            }
34
35            fn title(&self) -> String {
36                match self {
37                    #(#match_arms.title(),)*
38                }
39            }
40
41            fn subtitle(&self) -> Option<String> {
42                match self {
43                    #(#match_arms.subtitle(),)*
44                }
45            }
46
47            fn author(&self) -> Author {
48                match self {
49                    #(#match_arms.author(),)*
50                }
51            }
52
53            fn number(&self) -> Option<u32> {
54                match self {
55                    #(#match_arms.number(),)*
56                }
57            }
58
59            fn paragraph(&self) -> u32 {
60                match self {
61                    #(#match_arms.paragraph(),)*
62                }
63            }
64
65            fn text(&self) -> String {
66                match self {
67                    #(#match_arms.text(),)*
68                }
69            }
70        }
71    };
72
73    TokenStream::from(expanded)
74}