error_gen/
lib.rs

1extern crate proc_macro;
2
3use heck::TitleCase;
4use quote::quote;
5use syn::{
6    parse::{Parse, ParseStream},
7    parse_macro_input,
8};
9
10#[proc_macro_derive(ErrorGen)]
11pub fn error_gen_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
12    let input = parse_macro_input!(input as ErrorGenInput);
13    input.codegen().into()
14}
15
16struct ErrorGenInput {
17    root: syn::DeriveInput,
18}
19
20impl Parse for ErrorGenInput {
21    fn parse(input: ParseStream) -> syn::Result<Self> {
22        input.parse().map(ErrorGenInput::new)
23    }
24}
25
26impl ErrorGenInput {
27    fn new(root: syn::DeriveInput) -> Self {
28        ErrorGenInput { root }
29    }
30
31    fn codegen(self) -> proc_macro2::TokenStream {
32        let name = &self.root.ident;
33        let name_text = name.to_string().to_title_case().to_lowercase();
34        quote! {
35            impl std::fmt::Display for #name {
36                fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37                    f.write_str(#name_text)
38                }
39            }
40
41            impl std::error::Error for #name {}
42        }
43    }
44}