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}