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    OpenParen => "(",
60
61    CloseParen => ")",
63
64    OpenBracket => "[",
66
67    CloseBracket => "]",
69
70    OpenBrace => "{",
72
73    CloseBrace => "}",
75
76    Comma => ",",
78
79    Minus => "-",
81
82    Dot => ".",
84
85    Ellipsis => "...",
87
88    Colon => ":",
90
91    SemiColon => ";",
93
94    LessThan => "<",
96
97    Assign => "=",
99
100    GreaterThan => ">",
102
103    QMark => "?"
105}
106
107generate_terms_for_names! {
108    Or => "or",
110
111    Optional => "optional",
113
114    Async => "async",
116
117    Attribute => "attribute",
119
120    Callback => "callback",
122
123    Const => "const",
125
126    Deleter => "deleter",
128
129    Dictionary => "dictionary",
131
132    Enum => "enum",
134
135    Getter => "getter",
137
138    Includes => "includes",
140
141    Inherit => "inherit",
143
144    Interface => "interface",
146
147    Iterable => "iterable",
149
150    Maplike => "maplike",
152
153    Namespace => "namespace",
155
156    Partial => "partial",
158
159    Required => "required",
161
162    Setlike => "setlike",
164
165    Setter => "setter",
167
168    Static => "static",
170
171    Stringifier => "stringifier",
173
174    Typedef => "typedef",
176
177    Unrestricted => "unrestricted",
179
180    Symbol => "symbol",
182
183    NegInfinity => "-Infinity",
185
186    ByteString => "ByteString",
188
189    DOMString => "DOMString",
191
192    FrozenArray => "FrozenArray",
194
195    Infinity => "Infinity",
197
198    NaN => "NaN",
200
201    USVString => "USVString",
203
204    Any => "any",
206
207    Boolean => "boolean",
209
210    Byte => "byte",
212
213    Double => "double",
215
216    False => "false",
218
219    Float => "float",
221
222    Long => "long",
224
225    Null => "null",
227
228    Object => "object",
230
231    Octet => "octet",
233
234    Sequence => "sequence",
236
237    Short => "short",
239
240    True => "true",
242
243    Unsigned => "unsigned",
245
246    Undefined => "undefined",
248
249    Record => "record",
251
252    ArrayBuffer => "ArrayBuffer",
254
255    DataView => "DataView",
257
258    Int8Array => "Int8Array",
260
261    Int16Array => "Int16Array",
263
264    Int32Array => "Int32Array",
266
267    Uint8Array => "Uint8Array",
269
270    Uint16Array => "Uint16Array",
272
273    Uint32Array => "Uint32Array",
275
276    Uint8ClampedArray => "Uint8ClampedArray",
278
279    Float32Array => "Float32Array",
281
282    Float64Array => "Float64Array",
284
285    ArrayBufferView => "ArrayBufferView",
287
288    BufferSource => "BufferSource",
290
291    Promise => "Promise",
293
294    Error => "Error",
296
297    ReadOnly => "readonly",
299
300    Mixin => "mixin",
302
303    Implements => "implements",
305
306    LegacyCaller => "legacycaller",
308
309    Constructor => "constructor",
311}
312
313#[macro_export]
314macro_rules! term {
315    (OpenParen) => {
316        $crate::term::OpenParen
317    };
318    (CloseParen) => {
319        $crate::term::CloseParen
320    };
321    (OpenBracket) => {
322        $crate::term::OpenBracket
323    };
324    (CloseBracket) => {
325        $crate::term::CloseBracket
326    };
327    (OpenBrace) => {
328        $crate::term::OpenBrace
329    };
330    (CloseBrace) => {
331        $crate::term::CloseBrace
332    };
333    (,) => {
334        $crate::term::Comma
335    };
336    (-) => {
337        $crate::term::Minus
338    };
339    (.) => {
340        $crate::term::Dot
341    };
342    (...) => {
343        $crate::term::Ellipsis
344    };
345    (:) => {
346        $crate::term::Colon
347    };
348    (;) => {
349        $crate::term::SemiColon
350    };
351    (<) => {
352        $crate::term::LessThan
353    };
354    (=) => {
355        $crate::term::Assign
356    };
357    (>) => {
358        $crate::term::GreaterThan
359    };
360    (?) => {
361        $crate::term::QMark
362    };
363    (or) => {
364        $crate::term::Or
365    };
366    (optional) => {
367        $crate::term::Optional
368    };
369    (async) => {
370        $crate::term::Async
371    };
372    (attribute) => {
373        $crate::term::Attribute
374    };
375    (callback) => {
376        $crate::term::Callback
377    };
378    (const) => {
379        $crate::term::Const
380    };
381    (deleter) => {
382        $crate::term::Deleter
383    };
384    (dictionary) => {
385        $crate::term::Dictionary
386    };
387    (enum) => {
388        $crate::term::Enum
389    };
390    (getter) => {
391        $crate::term::Getter
392    };
393    (includes) => {
394        $crate::term::Includes
395    };
396    (inherit) => {
397        $crate::term::Inherit
398    };
399    (interface) => {
400        $crate::term::Interface
401    };
402    (iterable) => {
403        $crate::term::Iterable
404    };
405    (maplike) => {
406        $crate::term::Maplike
407    };
408    (namespace) => {
409        $crate::term::Namespace
410    };
411    (partial) => {
412        $crate::term::Partial
413    };
414    (required) => {
415        $crate::term::Required
416    };
417    (setlike) => {
418        $crate::term::Setlike
419    };
420    (setter) => {
421        $crate::term::Setter
422    };
423    (static) => {
424        $crate::term::Static
425    };
426    (stringifier) => {
427        $crate::term::Stringifier
428    };
429    (typedef) => {
430        $crate::term::Typedef
431    };
432    (unrestricted) => {
433        $crate::term::Unrestricted
434    };
435    (symbol) => {
436        $crate::term::Symbol
437    };
438    (- Infinity) => {
439        $crate::term::NegInfinity
440    };
441    (ByteString) => {
442        $crate::term::ByteString
443    };
444    (DOMString) => {
445        $crate::term::DOMString
446    };
447    (FrozenArray) => {
448        $crate::term::FrozenArray
449    };
450    (Infinity) => {
451        $crate::term::Infinity
452    };
453    (NaN) => {
454        $crate::term::NaN
455    };
456    (USVString) => {
457        $crate::term::USVString
458    };
459    (any) => {
460        $crate::term::Any
461    };
462    (boolean) => {
463        $crate::term::Boolean
464    };
465    (byte) => {
466        $crate::term::Byte
467    };
468    (double) => {
469        $crate::term::Double
470    };
471    (false) => {
472        $crate::term::False
473    };
474    (float) => {
475        $crate::term::Float
476    };
477    (long) => {
478        $crate::term::Long
479    };
480    (null) => {
481        $crate::term::Null
482    };
483    (object) => {
484        $crate::term::Object
485    };
486    (octet) => {
487        $crate::term::Octet
488    };
489    (sequence) => {
490        $crate::term::Sequence
491    };
492    (short) => {
493        $crate::term::Short
494    };
495    (true) => {
496        $crate::term::True
497    };
498    (unsigned) => {
499        $crate::term::Unsigned
500    };
501    (undefined) => {
502        $crate::term::Undefined
503    };
504    (record) => {
505        $crate::term::Record
506    };
507    (ArrayBuffer) => {
508        $crate::term::ArrayBuffer
509    };
510    (DataView) => {
511        $crate::term::DataView
512    };
513    (Int8Array) => {
514        $crate::term::Int8Array
515    };
516    (Int16Array) => {
517        $crate::term::Int16Array
518    };
519    (Int32Array) => {
520        $crate::term::Int32Array
521    };
522    (Uint8Array) => {
523        $crate::term::Uint8Array
524    };
525    (Uint16Array) => {
526        $crate::term::Uint16Array
527    };
528    (Uint32Array) => {
529        $crate::term::Uint32Array
530    };
531    (Uint8ClampedArray) => {
532        $crate::term::Uint8ClampedArray
533    };
534    (Float32Array) => {
535        $crate::term::Float32Array
536    };
537    (Float64Array) => {
538        $crate::term::Float64Array
539    };
540    (ArrayBufferView) => {
541        $crate::term::ArrayBufferView
542    };
543    (BufferSource) => {
544        $crate::term::BufferSource
545    };
546    (Promise) => {
547        $crate::term::Promise
548    };
549    (Error) => {
550        $crate::term::Error
551    };
552    (readonly) => {
553        $crate::term::ReadOnly
554    };
555    (mixin) => {
556        $crate::term::Mixin
557    };
558    (implements) => {
559        $crate::term::Implements
560    };
561    (legacycaller) => {
562        $crate::term::LegacyCaller
563    };
564    (constructor) => {
565        $crate::term::Constructor
566    };
567}
568
569#[cfg(test)]
570mod test {
571    macro_rules! generate_tests {
572        ($($m:ident, $typ:ident, $string:expr;)*) => {
573            $(
574                mod $m {
575                    use super::super::$typ;
576                    use crate::Parse;
577
578                    #[test]
579                    fn should_parse() {
580                        let (rem, parsed) = $typ::parse(concat!($string)).unwrap();
581                        assert_eq!(rem, "");
582                        assert_eq!(parsed, $typ);
583                    }
584
585                    #[test]
586                    fn should_parse_with_preceding_spaces() {
587                        let (rem, parsed) = $typ::parse(concat!("  ", $string)).unwrap();
588                        assert_eq!(rem, "");
589                        assert_eq!(parsed, $typ);
590                    }
591
592                    #[test]
593                    fn should_parse_with_succeeding_spaces() {
594                        let (rem, parsed) = $typ::parse(concat!($string, "  ")).unwrap();
595                        assert_eq!(rem, "");
596                        assert_eq!(parsed, $typ);
597                    }
598
599                    #[test]
600                    fn should_parse_with_surrounding_spaces() {
601                        let (rem, parsed) = $typ::parse(concat!("  ", $string, "  ")).unwrap();
602                        assert_eq!(rem, "");
603                        assert_eq!(parsed, $typ);
604                    }
605
606                    #[test]
607                    fn should_parse_if_anything_next() {
608                        let (rem, parsed) = $typ::parse(concat!($string, "  anything")).unwrap();
609                        assert_eq!(rem, "anything");
610                        assert_eq!(parsed, $typ);
611                    }
612                }
613            )*
614        };
615    }
616
617    generate_tests![
618        openparen, OpenParen, "(";
619        closeparen, CloseParen, ")";
620        openbracket, OpenBracket, "[";
621        closebracket, CloseBracket, "]";
622        openbrace, OpenBrace, "{";
623        closebrace, CloseBrace, "}";
624        comma, Comma, ",";
625        minus, Minus, "-";
626        dot, Dot, ".";
627        ellipsis, Ellipsis, "...";
628        colon, Colon, ":";
629        semicolon, SemiColon, ";";
630        lessthan, LessThan, "<";
631        assign, Assign, "=";
632        greaterthan, GreaterThan, ">";
633        qmark, QMark, "?";
634        or, Or, "or";
635        optional, Optional, "optional";
636        async_, Async, "async";
637        attribute, Attribute, "attribute";
638        callback, Callback, "callback";
639        const_, Const, "const";
640        deleter, Deleter, "deleter";
641        dictionary, Dictionary, "dictionary";
642        enum_, Enum, "enum";
643        getter, Getter, "getter";
644        includes, Includes, "includes";
645        inherit, Inherit, "inherit";
646        interface, Interface, "interface";
647        iterable, Iterable, "iterable";
648        maplike, Maplike, "maplike";
649        namespace, Namespace, "namespace";
650        partial, Partial, "partial";
651        required, Required, "required";
652        setlike, Setlike, "setlike";
653        setter, Setter, "setter";
654        static_, Static, "static";
655        stringifier, Stringifier, "stringifier";
656        typedef, Typedef, "typedef";
657        unrestricted, Unrestricted, "unrestricted";
658        symbol, Symbol, "symbol";
659        neginfinity, NegInfinity, "-Infinity";
660        bytestring, ByteString, "ByteString";
661        domstring, DOMString, "DOMString";
662        frozenarray, FrozenArray, "FrozenArray";
663        infinity, Infinity, "Infinity";
664        nan, NaN, "NaN";
665        usvstring, USVString, "USVString";
666        any, Any, "any";
667        boolean, Boolean, "boolean";
668        byte, Byte, "byte";
669        double, Double, "double";
670        false_, False, "false";
671        float, Float, "float";
672        long, Long, "long";
673        null, Null, "null";
674        object, Object, "object";
675        octet, Octet, "octet";
676        sequence, Sequence, "sequence";
677        short, Short, "short";
678        true_, True, "true";
679        unsigned, Unsigned, "unsigned";
680        undefined, Undefined, "undefined";
681        record, Record, "record";
682        arraybuffer, ArrayBuffer, "ArrayBuffer";
683        dataview, DataView, "DataView";
684        int8array, Int8Array, "Int8Array";
685        int16array, Int16Array, "Int16Array";
686        int32array, Int32Array, "Int32Array";
687        uint8array, Uint8Array, "Uint8Array";
688        uint16array, Uint16Array, "Uint16Array";
689        uint32array, Uint32Array, "Uint32Array";
690        uint8clampedarray, Uint8ClampedArray, "Uint8ClampedArray";
691        float32array, Float32Array, "Float32Array";
692        float64array, Float64Array, "Float64Array";
693        promise, Promise, "Promise";
694        error, Error, "Error";
695        implements, Implements, "implements";
696        legacycaller, LegacyCaller, "legacycaller";
697        constructor, Constructor, "constructor";
698    ];
699}