lib.rs 1.8 KB

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