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