spl_program_error_derive/
parser.rs

1//! Token parsing
2
3use {
4    proc_macro2::Ident,
5    syn::{
6        parse::{Parse, ParseStream},
7        token::Comma,
8        LitInt, Token,
9    },
10};
11
12/// Possible arguments to the `#[spl_program_error]` attribute
13pub struct SplProgramErrorArgs {
14    /// Whether to hash the error codes using `miraland_program::hash`
15    /// or to use the default error code assigned by `num_traits`.
16    pub hash_error_code_start: Option<u32>,
17}
18
19impl Parse for SplProgramErrorArgs {
20    fn parse(input: ParseStream) -> syn::Result<Self> {
21        if input.is_empty() {
22            return Ok(Self {
23                hash_error_code_start: None,
24            });
25        }
26        match SplProgramErrorArgParser::parse(input)? {
27            SplProgramErrorArgParser::HashErrorCodes { value, .. } => Ok(Self {
28                hash_error_code_start: Some(value.base10_parse::<u32>()?),
29            }),
30        }
31    }
32}
33
34/// Parser for args to the `#[spl_program_error]` attribute
35/// ie. `#[spl_program_error(hash_error_code_start = 1275525928)]`
36enum SplProgramErrorArgParser {
37    HashErrorCodes {
38        _ident: Ident,
39        _equals_sign: Token![=],
40        value: LitInt,
41        _comma: Option<Comma>,
42    },
43}
44
45impl Parse for SplProgramErrorArgParser {
46    fn parse(input: ParseStream) -> syn::Result<Self> {
47        let _ident = {
48            let ident = input.parse::<Ident>()?;
49            if ident != "hash_error_code_start" {
50                return Err(input.error("Expected argument 'hash_error_code_start'"));
51            }
52            ident
53        };
54        let _equals_sign = input.parse::<Token![=]>()?;
55        let value = input.parse::<LitInt>()?;
56        let _comma: Option<Comma> = input.parse().unwrap_or(None);
57        Ok(Self::HashErrorCodes {
58            _ident,
59            _equals_sign,
60            value,
61            _comma,
62        })
63    }
64}