aboutsummaryrefslogtreecommitdiff
path: root/azalea-inventory/azalea-inventory-macros/src/parse_macro.rs
blob: c415959d5a01ac92648254f3e19d6daf34e39cce (plain)
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
62
63
64
65
66
67
68
use syn::{
    Ident, LitInt, Token, braced,
    parse::{Parse, ParseStream, Result},
};

/// An identifier, colon, and number
/// `craft_result: 1`
pub struct Field {
    pub name: Ident,
    pub length: usize,
}
impl Parse for Field {
    fn parse(input: ParseStream) -> Result<Self> {
        let name = input.parse::<Ident>()?;
        let _ = input.parse::<Token![:]>()?;
        let length = input.parse::<LitInt>()?.base10_parse()?;
        Ok(Self { name, length })
    }
}

/// An identifier and a list of `Field` in curly brackets
/// ```rust,ignore
/// Player {
///     craft_result: 1,
///     ...
/// }
/// ```
pub struct Menu {
    /// The menu name, e.g. `Player`
    pub name: Ident,
    pub fields: Vec<Field>,
}

impl Parse for Menu {
    fn parse(input: ParseStream) -> Result<Self> {
        let name = input.parse::<Ident>()?;

        let content;
        braced!(content in input);
        let fields = content
            .parse_terminated(Field::parse, Token![,])?
            .into_iter()
            .collect();

        Ok(Self { name, fields })
    }
}

/// A list of `Menu`s
/// ```rust,ignore
/// Player {
///     craft_result: 1,
///     ...
/// },
/// ...
/// ```
pub struct DeclareMenus {
    pub menus: Vec<Menu>,
}
impl Parse for DeclareMenus {
    fn parse(input: ParseStream) -> Result<Self> {
        let menus = input
            .parse_terminated(Menu::parse, Token![,])?
            .into_iter()
            .collect();
        Ok(Self { menus })
    }
}