weedle/
attribute.rs

1use crate::argument::ArgumentList;
2use crate::common::{Bracketed, Identifier, Parenthesized, Punctuated};
3use crate::literal::StringLit;
4
5/// Parses a list of attributes. Ex: `[ attribute1, attribute2 ]`
6pub type ExtendedAttributeList<'a> = Bracketed<Punctuated<ExtendedAttribute<'a>, term!(,)>>;
7
8/// Matches comma separated identifier list
9pub type IdentifierList<'a> = Punctuated<Identifier<'a>, term!(,)>;
10
11ast_types! {
12    /// Parses on of the forms of attribute
13    enum ExtendedAttribute<'a> {
14        /// Parses an argument list. Ex: `Constructor((double x, double y))`
15        ///
16        /// (( )) means ( ) chars
17        ArgList(struct ExtendedAttributeArgList<'a> {
18            identifier: Identifier<'a>,
19            args: Parenthesized<ArgumentList<'a>>,
20        }),
21        /// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))`
22        ///
23        /// (( )) means ( ) chars
24        NamedArgList(struct ExtendedAttributeNamedArgList<'a> {
25            lhs_identifier: Identifier<'a>,
26            assign: term!(=),
27            rhs_identifier: Identifier<'a>,
28            args: Parenthesized<ArgumentList<'a>>,
29
30        }),
31        /// Parses an identifier list. Ex: `Exposed=((Window,Worker))`
32        ///
33        /// (( )) means ( ) chars
34        IdentList(struct ExtendedAttributeIdentList<'a> {
35            identifier: Identifier<'a>,
36            assign: term!(=),
37            list: Parenthesized<IdentifierList<'a>>,
38        }),
39        /// Parses an attribute with an identifier. Ex: `PutForwards=name`
40        #[derive(Copy)]
41        Ident(struct ExtendedAttributeIdent<'a> {
42            lhs_identifier: Identifier<'a>,
43            assign: term!(=),
44            rhs: IdentifierOrString<'a>,
45        }),
46        /// Parses a plain attribute. Ex: `Replaceable`
47        #[derive(Copy)]
48        NoArgs(struct ExtendedAttributeNoArgs<'a>(
49            Identifier<'a>,
50        )),
51    }
52
53    /// Parses `stringifier|static`
54    #[derive(Copy)]
55    enum IdentifierOrString<'a> {
56        Identifier(Identifier<'a>),
57        String(StringLit<'a>),
58    }
59}
60
61#[cfg(test)]
62mod test {
63    use super::*;
64    use crate::Parse;
65
66    test!(should_parse_attribute_no_args { "Replaceable" =>
67        "";
68        ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable"))
69    });
70
71    test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" =>
72        "";
73        ExtendedAttributeArgList;
74        identifier.0 == "Constructor";
75        args.body.list.len() == 2;
76    });
77
78    test!(should_parse_attribute_ident { "PutForwards=name" =>
79        "";
80        ExtendedAttributeIdent;
81        lhs_identifier.0 == "PutForwards";
82        rhs == IdentifierOrString::Identifier(Identifier("name"));
83    });
84
85    test!(should_parse_ident_list { "Exposed=(Window,Worker)" =>
86        "";
87        ExtendedAttributeIdentList;
88        identifier.0 == "Exposed";
89        list.body.list.len() == 2;
90    });
91
92    test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" =>
93        "";
94        ExtendedAttributeNamedArgList;
95        lhs_identifier.0 == "NamedConstructor";
96        rhs_identifier.0 == "Image";
97        args.body.list.len() == 1;
98    });
99}