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
//! Parser for the `syn` crate to parse the
//! `#[discriminator_hash_input("...")]` attribute

use {
    crate::error::SplDiscriminateError,
    syn::{
        parse::{Parse, ParseStream},
        token::Comma,
        Attribute, LitStr,
    },
};

/// Struct used for `syn` parsing of the hash_input attribute
/// #[discriminator_hash_input("...")]
struct HashInputValueParser {
    value: LitStr,
    _comma: Option<Comma>,
}

impl Parse for HashInputValueParser {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let value: LitStr = input.parse()?;
        let _comma: Option<Comma> = input.parse().unwrap_or(None);
        Ok(HashInputValueParser { value, _comma })
    }
}

/// Parses the hash_input from the `#[discriminator_hash_input("...")]`
/// attribute
pub fn parse_hash_input(attrs: &[Attribute]) -> Result<String, SplDiscriminateError> {
    match attrs
        .iter()
        .find(|a| a.path().is_ident("discriminator_hash_input"))
    {
        Some(attr) => {
            let parsed_args = attr
                .parse_args::<HashInputValueParser>()
                .map_err(|_| SplDiscriminateError::HashInputAttributeParseError)?;
            Ok(parsed_args.value.value())
        }
        None => Err(SplDiscriminateError::HashInputAttributeNotProvided),
    }
}