1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
extern crate proc_macro; use anchor_syn::codegen::error as error_codegen; use anchor_syn::parser::error as error_parser; use anchor_syn::ErrorArgs; use syn::parse_macro_input; /// Generates `Error` and `type Result<T> = Result<T, Error>` types to be /// used as return types from Anchor instruction handlers. Importantly, the /// attribute implements /// [`From`](https://doc.rust-lang.org/std/convert/trait.From.html) on the /// `ErrorCode` to support converting from the user defined error enum *into* /// the generated `Error`. /// /// # Example /// /// ```ignore /// use anchor_lang::prelude::*; /// /// #[program] /// mod errors { /// use super::*; /// pub fn hello(_ctx: Context<Hello>) -> Result<()> { /// Err(MyError::Hello.into()) /// } /// } /// /// #[derive(Accounts)] /// pub struct Hello {} /// /// #[error] /// pub enum MyError { /// #[msg("This is an error message clients will automatically display")] /// Hello, /// } /// ``` /// /// Note that we generate a new `Error` type so that we can return either the /// user defined error enum *or* a /// [`ProgramError`](../solana_program/enum.ProgramError.html), which is used /// pervasively, throughout solana program crates. The generated `Error` type /// should almost never be used directly, as the user defined error is /// preferred. In the example above, `MyError::Hello.into()`. /// /// # Msg /// /// The `#[msg(..)]` attribute is inert, and is used only as a marker so that /// parsers and IDLs can map error codes to error messages. #[proc_macro_attribute] pub fn error( args: proc_macro::TokenStream, input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let args = match args.is_empty() { true => None, false => Some(parse_macro_input!(args as ErrorArgs)), }; let mut error_enum = parse_macro_input!(input as syn::ItemEnum); let error = error_codegen::generate(error_parser::parse(&mut error_enum, args)); proc_macro::TokenStream::from(error) }