weedle/
interface.rs

1use crate::argument::ArgumentList;
2use crate::attribute::ExtendedAttributeList;
3use crate::common::{Generics, Identifier, Parenthesized};
4use crate::literal::ConstValue;
5use crate::types::{AttributedType, ConstType, ReturnType};
6
7/// Parses interface members
8pub type InterfaceMembers<'a> = Vec<InterfaceMember<'a>>;
9
10ast_types! {
11    /// Parses inheritance clause `: identifier`
12    #[derive(Copy)]
13    struct Inheritance<'a> {
14        colon: term!(:),
15        identifier: Identifier<'a>,
16    }
17
18    /// Parses one of the interface member variants
19    enum InterfaceMember<'a> {
20        /// Parses a const interface member `[attributes]? const type identifier = value;`
21        Const(struct ConstMember<'a> {
22            attributes: Option<ExtendedAttributeList<'a>>,
23            const_: term!(const),
24            const_type: ConstType<'a>,
25            identifier: Identifier<'a>,
26            assign: term!(=),
27            const_value: ConstValue<'a>,
28            semi_colon: term!(;),
29        }),
30        /// Parses `[attributes]? (stringifier|inherit|static)? readonly? attribute attributedtype identifier;`
31        Attribute(struct AttributeInterfaceMember<'a> {
32            attributes: Option<ExtendedAttributeList<'a>>,
33            modifier: Option<StringifierOrInheritOrStatic>,
34            readonly: Option<term!(readonly)>,
35            attribute: term!(attribute),
36            type_: AttributedType<'a>,
37            identifier: Identifier<'a>,
38            semi_colon: term!(;),
39        }),
40        /// Parses `[attributes]? constructor(( args ));`
41        ///
42        /// (( )) means ( ) chars
43        Constructor(struct ConstructorInterfaceMember<'a> {
44            attributes: Option<ExtendedAttributeList<'a>>,
45            constructor: term!(constructor),
46            args: Parenthesized<ArgumentList<'a>>,
47            semi_colon: term!(;),
48        }),
49        /// Parses `[attributes]? (stringifier|static)? special? returntype identifier? (( args ));`
50        ///
51        /// (( )) means ( ) chars
52        Operation(struct OperationInterfaceMember<'a> {
53            attributes: Option<ExtendedAttributeList<'a>>,
54            modifier: Option<StringifierOrStatic>,
55            special: Option<Special>,
56            return_type: ReturnType<'a>,
57            identifier: Option<Identifier<'a>>,
58            args: Parenthesized<ArgumentList<'a>>,
59            semi_colon: term!(;),
60        }),
61        /// Parses an iterable declaration `[attributes]? (iterable<attributedtype> | iterable<attributedtype, attributedtype>) ;`
62        Iterable(enum IterableInterfaceMember<'a> {
63            /// Parses an iterable declaration `[attributes]? iterable<attributedtype>;`
64            Single(struct SingleTypedIterable<'a> {
65                attributes: Option<ExtendedAttributeList<'a>>,
66                iterable: term!(iterable),
67                generics: Generics<AttributedType<'a>>,
68                semi_colon: term!(;),
69            }),
70            /// Parses an iterable declaration `[attributes]? iterable<attributedtype, attributedtype>;`
71            Double(struct DoubleTypedIterable<'a> {
72                attributes: Option<ExtendedAttributeList<'a>>,
73                iterable: term!(iterable),
74                generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>,
75                semi_colon: term!(;),
76            }),
77        }),
78        /// Parses an async iterable declaration `[attributes]? async (iterable<attributedtype> | iterable<attributedtype, attributedtype>) (( args ))? ;`
79        AsyncIterable(enum AsyncIterableInterfaceMember<'a> {
80            /// Parses an async iterable declaration `[attributes]? async iterable<attributedtype> (( args ))? ;`
81            Single(struct SingleTypedAsyncIterable<'a> {
82                attributes: Option<ExtendedAttributeList<'a>>,
83                async_iterable: (term!(async), term!(iterable)),
84                generics: Generics<AttributedType<'a>>,
85                args: Option<Parenthesized<ArgumentList<'a>>>,
86                semi_colon: term!(;),
87            }),
88            /// Parses an async iterable declaration `[attributes]? async iterable<attributedtype, attributedtype> (( args ))? ;`
89            Double(struct DoubleTypedAsyncIterable<'a> {
90                attributes: Option<ExtendedAttributeList<'a>>,
91                async_iterable: (term!(async), term!(iterable)),
92                generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>,
93                args: Option<Parenthesized<ArgumentList<'a>>>,
94                semi_colon: term!(;),
95            }),
96        }),
97        /// Parses an maplike declaration `[attributes]? readonly? maplike<attributedtype, attributedtype>;`
98        Maplike(struct MaplikeInterfaceMember<'a> {
99            attributes: Option<ExtendedAttributeList<'a>>,
100            readonly: Option<term!(readonly)>,
101            maplike: term!(maplike),
102            generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>,
103            semi_colon: term!(;),
104        }),
105        Setlike(struct SetlikeInterfaceMember<'a> {
106            attributes: Option<ExtendedAttributeList<'a>>,
107            readonly: Option<term!(readonly)>,
108            setlike: term!(setlike),
109            generics: Generics<AttributedType<'a>>,
110            semi_colon: term!(;),
111        }),
112        /// Parses `stringifier;`
113        #[derive(Default)]
114        Stringifier(struct StringifierMember<'a> {
115            attributes: Option<ExtendedAttributeList<'a>>,
116            stringifier: term!(stringifier),
117            semi_colon: term!(;),
118        }),
119    }
120
121    /// Parses one of the special keyword `getter|setter|deleter`
122    #[derive(Copy)]
123    enum Special {
124        Getter(term!(getter)),
125        Setter(term!(setter)),
126        Deleter(term!(deleter)),
127        LegacyCaller(term!(legacycaller)),
128    }
129
130    /// Parses `stringifier|inherit|static`
131    #[derive(Copy)]
132    enum StringifierOrInheritOrStatic {
133        Stringifier(term!(stringifier)),
134        Inherit(term!(inherit)),
135        Static(term!(static)),
136    }
137
138    /// Parses `stringifier|static`
139    #[derive(Copy)]
140    enum StringifierOrStatic {
141        Stringifier(term!(stringifier)),
142        Static(term!(static)),
143    }
144}
145
146#[cfg(test)]
147mod test {
148    use super::*;
149    use crate::Parse;
150
151    test!(should_parse_stringifier_member { "stringifier;" =>
152        "";
153        StringifierMember;
154    });
155
156    test!(should_parse_stringifier_or_static { "static" =>
157        "";
158        StringifierOrStatic;
159    });
160
161    test!(should_parse_stringifier_or_inherit_or_static { "inherit" =>
162        "";
163        StringifierOrInheritOrStatic;
164    });
165
166    test!(should_parse_setlike_interface_member { "readonly setlike<long>;" =>
167        "";
168        SetlikeInterfaceMember;
169        attributes.is_none();
170        readonly == Some(term!(readonly));
171    });
172
173    test!(should_parse_maplike_interface_member { "readonly maplike<long, short>;" =>
174        "";
175        MaplikeInterfaceMember;
176        attributes.is_none();
177        readonly == Some(term!(readonly));
178    });
179
180    test!(should_parse_attribute_interface_member { "readonly attribute unsigned long width;" =>
181        "";
182        AttributeInterfaceMember;
183        attributes.is_none();
184        readonly == Some(term!(readonly));
185        identifier.0 == "width";
186    });
187
188    test!(should_parse_double_typed_iterable { "iterable<long, long>;" =>
189        "";
190        DoubleTypedIterable;
191        attributes.is_none();
192    });
193
194    test!(should_parse_single_typed_iterable { "iterable<long>;" =>
195        "";
196        SingleTypedIterable;
197        attributes.is_none();
198    });
199
200    test!(should_parse_double_typed_async_iterable { "async iterable<long, long>;" =>
201        "";
202        DoubleTypedAsyncIterable;
203        attributes.is_none();
204        args.is_none();
205    });
206
207    test!(should_parse_double_typed_async_iterable_with_args { "async iterable<long, long>(long a);" =>
208        "";
209        DoubleTypedAsyncIterable;
210        attributes.is_none();
211        args.is_some();
212    });
213
214    test!(should_parse_single_typed_async_iterable { "async iterable<long>;" =>
215        "";
216        SingleTypedAsyncIterable;
217        attributes.is_none();
218        args.is_none();
219    });
220
221    test!(should_parse_single_typed_async_iterable_with_args { "async iterable<long>(long a);" =>
222        "";
223        SingleTypedAsyncIterable;
224        attributes.is_none();
225        args.is_some();
226    });
227
228    test!(should_parse_constructor_interface_member { "constructor(long a);" =>
229        "";
230        ConstructorInterfaceMember;
231        attributes.is_none();
232    });
233
234    test!(should_parse_operation_interface_member { "undefined readString(long a, long b);" =>
235        "";
236        OperationInterfaceMember;
237        attributes.is_none();
238        modifier.is_none();
239        special.is_none();
240        identifier.is_some();
241    });
242
243    test!(should_parse_const_member { "const long name = 5;" =>
244        "";
245        ConstMember;
246        attributes.is_none();
247        identifier.0 == "name";
248    });
249}