typhoon_errors_macro/
lib.rs1use {
2 proc_macro::TokenStream,
3 quote::{quote, ToTokens},
4 syn::parse_macro_input,
5 typhoon_syn::Errors,
6};
7
8#[proc_macro_derive(TyphoonError, attributes(msg))]
26pub fn typhoon_error(input: TokenStream) -> TokenStream {
27 let errors_token = parse_macro_input!(input as Errors);
28
29 let name = &errors_token.name;
30
31 let (to_str_arms, try_from_arms) = errors_token
32 .variants
33 .iter()
34 .map(|v| {
35 let variant_name = &v.name;
36 let msg = &v.msg;
37 let discriminant = &v.discriminant;
38 (
39 quote!(#name::#variant_name => #msg,),
40 quote!(#discriminant => Ok(#name::#variant_name),),
41 )
42 })
43 .collect::<(Vec<_>, Vec<_>)>();
44
45 quote! {
46 impl TryFrom<u32> for #name {
47 type Error = ProgramError;
48
49 fn try_from(value: u32) -> Result<Self, Self::Error> {
50 match value {
51 #(#try_from_arms)*
52 _ => Err(ProgramError::InvalidArgument),
53 }
54 }
55 }
56
57 impl ToStr for #name {
58 fn to_str(&self) -> &'static str
59 {
60 match self {
61 #(#to_str_arms)*
62 }
63 }
64 }
65
66 impl From<#name> for Error {
67 fn from(value: #name) -> Self {
68 Error::new(ProgramError::Custom(value as u32))
69 }
70 }
71 }
72 .into_token_stream()
73 .into()
74}