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}