croncat_errors_macro/
lib.rs1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Error, Ident, Variant};
6
7#[proc_macro_attribute]
8pub fn croncat_error(_attrs: TokenStream, input: TokenStream) -> TokenStream {
9 let mut input = parse_macro_input!(input as DeriveInput);
10 let enum_name = input.ident.clone();
11
12 if !input.attrs.iter().any(|attr| attr.path.is_ident("derive")) {
14 let msg = "😻 Please move the `#[croncat_error]` macro above the `#[derive]` attribute with the `Error` trait. 😻";
15 let error = Error::new_spanned(enum_name, msg).to_compile_error();
16 return TokenStream::from(quote! {
17 #error
18 });
19 }
20
21 let mut is_croncat_error_present = false;
22 if let Data::Enum(DataEnum {
23 ref mut variants, ..
24 }) = input.data
25 {
26 for variant in variants.iter() {
28 if variant.ident == Ident::new("CronCatError", variant.ident.span()) {
29 is_croncat_error_present = true;
30 }
31 }
32
33 if !is_croncat_error_present {
34 let croncat_error_variant: Variant = syn::parse_quote! {
40 #[error("CronCat error: {err:?}")]
41 CronCatError {
42 err: croncat_integration_utils::error::CronCatContractError,
43 }
44 };
45 variants.push(croncat_error_variant);
46 }
47 }
48
49 let expanded = quote! {
58 #input
59
60 impl From<croncat_integration_utils::error::CronCatContractError> for #enum_name {
61 fn from(error: croncat_integration_utils::error::CronCatContractError) -> Self {
62 #enum_name::CronCatError {
63 err: error,
64 }
65 }
66 }
67 };
68
69 TokenStream::from(expanded)
70}