weedle/
term.rs

1macro_rules! generate_terms {
2    ($( $(#[$attr:meta])* $typ:ident => $tok:expr ),*) => {
3        $(
4            $(#[$attr])*
5            #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
6            pub struct $typ;
7
8            impl<'a> $crate::Parse<'a> for $typ {
9                parser!(nom::combinator::value(
10                    $typ,
11                    crate::whitespace::ws(
12                        nom::bytes::complete::tag($tok)
13                    )
14                ));
15            }
16        )*
17    };
18}
19
20struct AlphaNumUnderscoreDash;
21
22impl nom::FindToken<char> for AlphaNumUnderscoreDash {
23    fn find_token(&self, token: char) -> bool {
24        crate::common::is_alphanum_underscore_dash(token)
25    }
26}
27
28pub(crate) fn ident_tag(tag: &'static str) -> impl FnMut(&str) -> nom::IResult<&str, &str> {
29    move |input| {
30        nom::sequence::terminated(
31            nom::bytes::complete::tag(tag),
32            nom::combinator::not(nom::combinator::map_parser(
33                nom::bytes::complete::take(1usize),
34                nom::bytes::complete::is_a(AlphaNumUnderscoreDash),
35            )),
36        )(input)
37    }
38}
39
40macro_rules! generate_terms_for_names {
41    ($( $(#[$attr:meta])* $typ:ident => $tok:expr,)*) => {
42        $(
43            $(#[$attr])*
44            #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
45            pub struct $typ;
46
47            impl<'a> $crate::Parse<'a> for $typ {
48                parser!(nom::combinator::value(
49                    $typ,
50                    $crate::whitespace::ws($crate::term::ident_tag($tok))
51                ));
52            }
53        )*
54    };
55}
56
57generate_terms! {
58    /// Represents the terminal symbol `(`
59    OpenParen => "(",
60
61    /// Represents the terminal symbol `)`
62    CloseParen => ")",
63
64    /// Represents the terminal symbol `[`
65    OpenBracket => "[",
66
67    /// Represents the terminal symbol `]`
68    CloseBracket => "]",
69
70    /// Represents the terminal symbol `{`
71    OpenBrace => "{",
72
73    /// Represents the terminal symbol `}`
74    CloseBrace => "}",
75
76    /// Represents the terminal symbol `,`
77    Comma => ",",
78
79    /// Represents the terminal symbol `-`
80    Minus => "-",
81
82    /// Represents the terminal symbol `.`
83    Dot => ".",
84
85    /// Represents the terminal symbol `...`
86    Ellipsis => "...",
87
88    /// Represents the terminal symbol `:`
89    Colon => ":",
90
91    /// Represents the terminal symbol `;`
92    SemiColon => ";",
93
94    /// Represents the terminal symbol `<`
95    LessThan => "<",
96
97    /// Represents the terminal symbol `=`
98    Assign => "=",
99
100    /// Represents the terminal symbol `>`
101    GreaterThan => ">",
102
103    /// Represents the terminal symbol `?`
104    QMark => "?",
105
106    /// Represents the wildcard symbol `*`
107    Asterisk => "*"
108}
109
110generate_terms_for_names! {
111    /// Represents the terminal symbol `or`
112    Or => "or",
113
114    /// Represents the terminal symbol `optional`
115    Optional => "optional",
116
117    /// Represents the terminal symbol `async`
118    Async => "async",
119
120    /// Represents the terminal symbol `attribute`
121    Attribute => "attribute",
122
123    /// Represents the terminal symbol `callback`
124    Callback => "callback",
125
126    /// Represents the terminal symbol `const`
127    Const => "const",
128
129    /// Represents the terminal symbol `deleter`
130    Deleter => "deleter",
131
132    /// Represents the terminal symbol `dictionary`
133    Dictionary => "dictionary",
134
135    /// Represents the terminal symbol `enum`
136    Enum => "enum",
137
138    /// Represents the terminal symbol `getter`
139    Getter => "getter",
140
141    /// Represents the terminal symbol `includes`
142    Includes => "includes",
143
144    /// Represents the terminal symbol `inherit`
145    Inherit => "inherit",
146
147    /// Represents the terminal symbol `interface`
148    Interface => "interface",
149
150    /// Represents the terminal symbol `iterable`
151    Iterable => "iterable",
152
153    /// Represents the terminal symbol `maplike`
154    Maplike => "maplike",
155
156    /// Represents the terminal symbol `namespace`
157    Namespace => "namespace",
158
159    /// Represents the terminal symbol `partial`
160    Partial => "partial",
161
162    /// Represents the terminal symbol `required`
163    Required => "required",
164
165    /// Represents the terminal symbol `setlike`
166    Setlike => "setlike",
167
168    /// Represents the terminal symbol `setter`
169    Setter => "setter",
170
171    /// Represents the terminal symbol `static`
172    Static => "static",
173
174    /// Represents the terminal symbol `stringifier`
175    Stringifier => "stringifier",
176
177    /// Represents the terminal symbol `typedef`
178    Typedef => "typedef",
179
180    /// Represents the terminal symbol `unrestricted`
181    Unrestricted => "unrestricted",
182
183    /// Represents the terminal symbol `symbol`
184    Symbol => "symbol",
185
186    /// Represents the terminal symbol `Infinity`
187    NegInfinity => "-Infinity",
188
189    /// Represents the terminal symbol `ByteString`
190    ByteString => "ByteString",
191
192    /// Represents the terminal symbol `DOMString`
193    DOMString => "DOMString",
194
195    /// Represents the terminal symbol `FrozenArray`
196    FrozenArray => "FrozenArray",
197
198    /// Represents the terminal symbol `ObservableArray`
199    ObservableArray => "ObservableArray",
200
201    /// Represents the terminal symbol `Infinity`
202    Infinity => "Infinity",
203
204    /// Represents the terminal symbol `NaN`
205    NaN => "NaN",
206
207    /// Represents the terminal symbol `USVString`
208    USVString => "USVString",
209
210    /// Represents the terminal symbol `any`
211    Any => "any",
212
213    /// Represents the terminal symbol `boolean`
214    Boolean => "boolean",
215
216    /// Represents the terminal symbol `byte`
217    Byte => "byte",
218
219    /// Represents the terminal symbol `double`
220    Double => "double",
221
222    /// Represents the terminal symbol `false`
223    False => "false",
224
225    /// Represents the terminal symbol `float`
226    Float => "float",
227
228    /// Represents the terminal symbol `long`
229    Long => "long",
230
231    /// Represents the terminal symbol `null`
232    Null => "null",
233
234    /// Represents the terminal symbol `object`
235    Object => "object",
236
237    /// Represents the terminal symbol `octet`
238    Octet => "octet",
239
240    /// Represents the terminal symbol `sequence`
241    Sequence => "sequence",
242
243    /// Represents the terminal symbol `short`
244    Short => "short",
245
246    /// Represents the terminal symbol `true`
247    True => "true",
248
249    /// Represents the terminal symbol `unsigned`
250    Unsigned => "unsigned",
251
252    /// Represents the terminal symbol `undefined`
253    Undefined => "undefined",
254
255    /// Represents the terminal symbol `record`
256    Record => "record",
257
258    /// Represents the terminal symbol `ArrayBuffer`
259    ArrayBuffer => "ArrayBuffer",
260
261    /// Represents the terminal symbol `DataView`
262    DataView => "DataView",
263
264    /// Represents the terminal symbol `Int8Array`
265    Int8Array => "Int8Array",
266
267    /// Represents the terminal symbol `Int16Array`
268    Int16Array => "Int16Array",
269
270    /// Represents the terminal symbol `Int32Array`
271    Int32Array => "Int32Array",
272
273    /// Represents the terminal symbol `Uint8Array`
274    Uint8Array => "Uint8Array",
275
276    /// Represents the terminal symbol `Uint16Array`
277    Uint16Array => "Uint16Array",
278
279    /// Represents the terminal symbol `Uint32Array`
280    Uint32Array => "Uint32Array",
281
282    /// Represents the terminal symbol `Uint8ClampedArray`
283    Uint8ClampedArray => "Uint8ClampedArray",
284
285    /// Represents the terminal symbol `Float32Array`
286    Float32Array => "Float32Array",
287
288    /// Represents the terminal symbol `Float64Array`
289    Float64Array => "Float64Array",
290
291    /// Represents the terminal symbol `ArrayBufferView`
292    ArrayBufferView => "ArrayBufferView",
293
294    /// Represents the terminal symbol `BufferSource
295    BufferSource => "BufferSource",
296
297    /// Represents the terminal symbol `Promise`
298    Promise => "Promise",
299
300    /// Represents the terminal symbol `Error`
301    Error => "Error",
302
303    /// Represents the terminal symbol `readonly`
304    ReadOnly => "readonly",
305
306    /// Represents the terminal symbol `mixin`
307    Mixin => "mixin",
308
309    /// Represents the terminal symbol `implements`
310    Implements => "implements",
311
312    /// Represents the terminal symbol `legacycaller`
313    LegacyCaller => "legacycaller",
314
315    /// Represents the terminal symbol `constructor`
316    Constructor => "constructor",
317}
318
319#[macro_export]
320macro_rules! term {
321    (OpenParen) => {
322        $crate::term::OpenParen
323    };
324    (CloseParen) => {
325        $crate::term::CloseParen
326    };
327    (OpenBracket) => {
328        $crate::term::OpenBracket
329    };
330    (CloseBracket) => {
331        $crate::term::CloseBracket
332    };
333    (OpenBrace) => {
334        $crate::term::OpenBrace
335    };
336    (CloseBrace) => {
337        $crate::term::CloseBrace
338    };
339    (,) => {
340        $crate::term::Comma
341    };
342    (-) => {
343        $crate::term::Minus
344    };
345    (.) => {
346        $crate::term::Dot
347    };
348    (...) => {
349        $crate::term::Ellipsis
350    };
351    (:) => {
352        $crate::term::Colon
353    };
354    (;) => {
355        $crate::term::SemiColon
356    };
357    (<) => {
358        $crate::term::LessThan
359    };
360    (=) => {
361        $crate::term::Assign
362    };
363    (>) => {
364        $crate::term::GreaterThan
365    };
366    (?) => {
367        $crate::term::QMark
368    };
369    (*) => {
370        $crate::term::Asterisk
371    };
372    (or) => {
373        $crate::term::Or
374    };
375    (optional) => {
376        $crate::term::Optional
377    };
378    (async) => {
379        $crate::term::Async
380    };
381    (attribute) => {
382        $crate::term::Attribute
383    };
384    (callback) => {
385        $crate::term::Callback
386    };
387    (const) => {
388        $crate::term::Const
389    };
390    (deleter) => {
391        $crate::term::Deleter
392    };
393    (dictionary) => {
394        $crate::term::Dictionary
395    };
396    (enum) => {
397        $crate::term::Enum
398    };
399    (getter) => {
400        $crate::term::Getter
401    };
402    (includes) => {
403        $crate::term::Includes
404    };
405    (inherit) => {
406        $crate::term::Inherit
407    };
408    (interface) => {
409        $crate::term::Interface
410    };
411    (iterable) => {
412        $crate::term::Iterable
413    };
414    (maplike) => {
415        $crate::term::Maplike
416    };
417    (namespace) => {
418        $crate::term::Namespace
419    };
420    (partial) => {
421        $crate::term::Partial
422    };
423    (required) => {
424        $crate::term::Required
425    };
426    (setlike) => {
427        $crate::term::Setlike
428    };
429    (setter) => {
430        $crate::term::Setter
431    };
432    (static) => {
433        $crate::term::Static
434    };
435    (stringifier) => {
436        $crate::term::Stringifier
437    };
438    (typedef) => {
439        $crate::term::Typedef
440    };
441    (unrestricted) => {
442        $crate::term::Unrestricted
443    };
444    (symbol) => {
445        $crate::term::Symbol
446    };
447    (- Infinity) => {
448        $crate::term::NegInfinity
449    };
450    (ByteString) => {
451        $crate::term::ByteString
452    };
453    (DOMString) => {
454        $crate::term::DOMString
455    };
456    (FrozenArray) => {
457        $crate::term::FrozenArray
458    };
459    (ObservableArray) => {
460        $crate::term::ObservableArray
461    };
462    (Infinity) => {
463        $crate::term::Infinity
464    };
465    (NaN) => {
466        $crate::term::NaN
467    };
468    (USVString) => {
469        $crate::term::USVString
470    };
471    (any) => {
472        $crate::term::Any
473    };
474    (boolean) => {
475        $crate::term::Boolean
476    };
477    (byte) => {
478        $crate::term::Byte
479    };
480    (double) => {
481        $crate::term::Double
482    };
483    (false) => {
484        $crate::term::False
485    };
486    (float) => {
487        $crate::term::Float
488    };
489    (long) => {
490        $crate::term::Long
491    };
492    (null) => {
493        $crate::term::Null
494    };
495    (object) => {
496        $crate::term::Object
497    };
498    (octet) => {
499        $crate::term::Octet
500    };
501    (sequence) => {
502        $crate::term::Sequence
503    };
504    (short) => {
505        $crate::term::Short
506    };
507    (true) => {
508        $crate::term::True
509    };
510    (unsigned) => {
511        $crate::term::Unsigned
512    };
513    (undefined) => {
514        $crate::term::Undefined
515    };
516    (record) => {
517        $crate::term::Record
518    };
519    (ArrayBuffer) => {
520        $crate::term::ArrayBuffer
521    };
522    (DataView) => {
523        $crate::term::DataView
524    };
525    (Int8Array) => {
526        $crate::term::Int8Array
527    };
528    (Int16Array) => {
529        $crate::term::Int16Array
530    };
531    (Int32Array) => {
532        $crate::term::Int32Array
533    };
534    (Uint8Array) => {
535        $crate::term::Uint8Array
536    };
537    (Uint16Array) => {
538        $crate::term::Uint16Array
539    };
540    (Uint32Array) => {
541        $crate::term::Uint32Array
542    };
543    (Uint8ClampedArray) => {
544        $crate::term::Uint8ClampedArray
545    };
546    (Float32Array) => {
547        $crate::term::Float32Array
548    };
549    (Float64Array) => {
550        $crate::term::Float64Array
551    };
552    (ArrayBufferView) => {
553        $crate::term::ArrayBufferView
554    };
555    (BufferSource) => {
556        $crate::term::BufferSource
557    };
558    (Promise) => {
559        $crate::term::Promise
560    };
561    (Error) => {
562        $crate::term::Error
563    };
564    (readonly) => {
565        $crate::term::ReadOnly
566    };
567    (mixin) => {
568        $crate::term::Mixin
569    };
570    (implements) => {
571        $crate::term::Implements
572    };
573    (legacycaller) => {
574        $crate::term::LegacyCaller
575    };
576    (constructor) => {
577        $crate::term::Constructor
578    };
579}
580
581#[cfg(test)]
582mod test {
583    macro_rules! generate_tests {
584        ($($m:ident, $typ:ident, $string:expr;)*) => {
585            $(
586                mod $m {
587                    use super::super::$typ;
588                    use crate::Parse;
589
590                    #[test]
591                    fn should_parse() {
592                        let (rem, parsed) = $typ::parse(concat!($string)).unwrap();
593                        assert_eq!(rem, "");
594                        assert_eq!(parsed, $typ);
595                    }
596
597                    #[test]
598                    fn should_parse_with_preceding_spaces() {
599                        let (rem, parsed) = $typ::parse(concat!("  ", $string)).unwrap();
600                        assert_eq!(rem, "");
601                        assert_eq!(parsed, $typ);
602                    }
603
604                    #[test]
605                    fn should_parse_with_succeeding_spaces() {
606                        let (rem, parsed) = $typ::parse(concat!($string, "  ")).unwrap();
607                        assert_eq!(rem, "");
608                        assert_eq!(parsed, $typ);
609                    }
610
611                    #[test]
612                    fn should_parse_with_surrounding_spaces() {
613                        let (rem, parsed) = $typ::parse(concat!("  ", $string, "  ")).unwrap();
614                        assert_eq!(rem, "");
615                        assert_eq!(parsed, $typ);
616                    }
617
618                    #[test]
619                    fn should_parse_if_anything_next() {
620                        let (rem, parsed) = $typ::parse(concat!($string, "  anything")).unwrap();
621                        assert_eq!(rem, "anything");
622                        assert_eq!(parsed, $typ);
623                    }
624                }
625            )*
626        };
627    }
628
629    generate_tests![
630        openparen, OpenParen, "(";
631        closeparen, CloseParen, ")";
632        openbracket, OpenBracket, "[";
633        closebracket, CloseBracket, "]";
634        openbrace, OpenBrace, "{";
635        closebrace, CloseBrace, "}";
636        comma, Comma, ",";
637        minus, Minus, "-";
638        dot, Dot, ".";
639        ellipsis, Ellipsis, "...";
640        colon, Colon, ":";
641        semicolon, SemiColon, ";";
642        lessthan, LessThan, "<";
643        assign, Assign, "=";
644        greaterthan, GreaterThan, ">";
645        qmark, QMark, "?";
646        asterisk, Asterisk, "*";
647        or, Or, "or";
648        optional, Optional, "optional";
649        async_, Async, "async";
650        attribute, Attribute, "attribute";
651        callback, Callback, "callback";
652        const_, Const, "const";
653        deleter, Deleter, "deleter";
654        dictionary, Dictionary, "dictionary";
655        enum_, Enum, "enum";
656        getter, Getter, "getter";
657        includes, Includes, "includes";
658        inherit, Inherit, "inherit";
659        interface, Interface, "interface";
660        iterable, Iterable, "iterable";
661        maplike, Maplike, "maplike";
662        namespace, Namespace, "namespace";
663        partial, Partial, "partial";
664        required, Required, "required";
665        setlike, Setlike, "setlike";
666        setter, Setter, "setter";
667        static_, Static, "static";
668        stringifier, Stringifier, "stringifier";
669        typedef, Typedef, "typedef";
670        unrestricted, Unrestricted, "unrestricted";
671        symbol, Symbol, "symbol";
672        neginfinity, NegInfinity, "-Infinity";
673        bytestring, ByteString, "ByteString";
674        domstring, DOMString, "DOMString";
675        frozenarray, FrozenArray, "FrozenArray";
676        observablearray, ObservableArray, "ObservableArray";
677        infinity, Infinity, "Infinity";
678        nan, NaN, "NaN";
679        usvstring, USVString, "USVString";
680        any, Any, "any";
681        boolean, Boolean, "boolean";
682        byte, Byte, "byte";
683        double, Double, "double";
684        false_, False, "false";
685        float, Float, "float";
686        long, Long, "long";
687        null, Null, "null";
688        object, Object, "object";
689        octet, Octet, "octet";
690        sequence, Sequence, "sequence";
691        short, Short, "short";
692        true_, True, "true";
693        unsigned, Unsigned, "unsigned";
694        undefined, Undefined, "undefined";
695        record, Record, "record";
696        arraybuffer, ArrayBuffer, "ArrayBuffer";
697        dataview, DataView, "DataView";
698        int8array, Int8Array, "Int8Array";
699        int16array, Int16Array, "Int16Array";
700        int32array, Int32Array, "Int32Array";
701        uint8array, Uint8Array, "Uint8Array";
702        uint16array, Uint16Array, "Uint16Array";
703        uint32array, Uint32Array, "Uint32Array";
704        uint8clampedarray, Uint8ClampedArray, "Uint8ClampedArray";
705        float32array, Float32Array, "Float32Array";
706        float64array, Float64Array, "Float64Array";
707        promise, Promise, "Promise";
708        error, Error, "Error";
709        implements, Implements, "implements";
710        legacycaller, LegacyCaller, "legacycaller";
711        constructor, Constructor, "constructor";
712    ];
713}