masterror_derive/
lib.rs

1//! Derive macro for `masterror::Error`.
2//!
3//! This crate is not intended to be used directly. Re-exported as
4//! `masterror::Error`.
5
6mod app_error_impl;
7mod display;
8mod error_trait;
9mod from_impl;
10mod input;
11mod masterror_impl;
12mod span;
13mod template_support;
14
15use proc_macro::TokenStream;
16use quote::quote;
17use syn::{DeriveInput, Error, parse_macro_input};
18
19#[proc_macro_derive(Error, attributes(error, source, from, backtrace, app_error, provide))]
20pub fn derive_error(tokens: TokenStream) -> TokenStream {
21    let input = parse_macro_input!(tokens as DeriveInput);
22    match expand(input) {
23        Ok(stream) => stream.into(),
24        Err(err) => err.to_compile_error().into()
25    }
26}
27
28#[proc_macro_derive(
29    Masterror,
30    attributes(error, source, from, backtrace, masterror, provide)
31)]
32pub fn derive_masterror(tokens: TokenStream) -> TokenStream {
33    let input = parse_macro_input!(tokens as DeriveInput);
34    match expand_masterror(input) {
35        Ok(stream) => stream.into(),
36        Err(err) => err.to_compile_error().into()
37    }
38}
39
40fn expand(input: DeriveInput) -> Result<proc_macro2::TokenStream, Error> {
41    let parsed = input::parse_input(input)?;
42    let display_impl = display::expand(&parsed)?;
43    let error_impl = error_trait::expand(&parsed)?;
44    let from_impls = from_impl::expand(&parsed)?;
45    let app_error_impls = app_error_impl::expand(&parsed)?;
46
47    Ok(quote! {
48        #display_impl
49        #error_impl
50        #(#from_impls)*
51        #(#app_error_impls)*
52    })
53}
54
55fn expand_masterror(input: DeriveInput) -> Result<proc_macro2::TokenStream, Error> {
56    let parsed = input::parse_input(input)?;
57    let display_impl = display::expand(&parsed)?;
58    let error_impl = error_trait::expand(&parsed)?;
59    let from_impls = from_impl::expand(&parsed)?;
60    let masterror_impl = masterror_impl::expand(&parsed)?;
61
62    Ok(quote! {
63        #display_impl
64        #error_impl
65        #(#from_impls)*
66        #masterror_impl
67    })
68}