123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- use crate::Error;
- use quote::quote;
- pub fn generate(error: Error) -> proc_macro2::TokenStream {
- let error_enum = &error.raw_enum;
- let enum_name = &error.ident;
- // Each arm of the `match` statement for implementing `std::fmt::Display`
- // on the user defined error code.
- let display_variant_dispatch: Vec<proc_macro2::TokenStream> = error
- .raw_enum
- .variants
- .iter()
- .enumerate()
- .map(|(idx, variant)| {
- let ident = &variant.ident;
- let error_code = &error.codes[idx];
- let display_msg = match &error_code.msg {
- None => {
- quote! {
- <Self as std::fmt::Debug>::fmt(self, fmt)
- }
- }
- Some(msg) => {
- quote! {
- write!(fmt, #msg)
- }
- }
- };
- quote! {
- #enum_name::#ident => #display_msg
- }
- })
- .collect();
- // Each arm of the `match` statement for implementing the `name` function
- // on the user defined error code.
- let name_variant_dispatch: Vec<proc_macro2::TokenStream> = error
- .raw_enum
- .variants
- .iter()
- .map(|variant| {
- let ident = &variant.ident;
- let ident_name = ident.to_string();
- quote! {
- #enum_name::#ident => #ident_name.to_string()
- }
- })
- .collect();
- let offset = match error.args {
- None => quote! { anchor_lang::error::ERROR_CODE_OFFSET},
- Some(args) => {
- let offset = &args.offset;
- quote! { #offset }
- }
- };
- quote! {
- #[derive(std::fmt::Debug, Clone, Copy)]
- #[repr(u32)]
- #error_enum
- impl #enum_name {
- /// Gets the name of this [#enum_name].
- pub fn name(&self) -> String {
- match self {
- #(#name_variant_dispatch),*
- }
- }
- }
- impl From<#enum_name> for u32 {
- fn from(e: #enum_name) -> u32 {
- e as u32 + #offset
- }
- }
- impl From<#enum_name> for anchor_lang::error::Error {
- fn from(error_code: #enum_name) -> Error {
- anchor_lang::error::Error::from(
- anchor_lang::error::AnchorError {
- error_name: error_code.name(),
- error_code_number: error_code.into(),
- error_msg: error_code.to_string(),
- source: None,
- account_name: None
- }
- )
- }
- }
- impl std::fmt::Display for #enum_name {
- fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
- match self {
- #(#display_variant_dispatch),*
- }
- }
- }
- }
- }
|