blob: 9ecf07b4951707e994191f9590d54757b83f9ec1 [file] [log] [blame]
Louis Kureuil Personc0beaf32018-09-05 00:12:43 +02001use buffer::Cursor;
2use token::Token;
3
4pub trait Keyword {
5 fn ident() -> &'static str;
6
7 fn display() -> &'static str;
8}
9
10impl<K: Keyword> Token for K {
11 fn peek(cursor: Cursor) -> bool {
12 if let Some((ident, _rest)) = cursor.ident() {
13 ident == K::ident()
14 } else {
15 false
16 }
17 }
18
19 fn display() -> &'static str {
20 K::display()
21 }
22}
23
24#[macro_export]
25macro_rules! custom_keyword {
26 ($ident:ident) => {
27 custom_keyword_internal!({ pub(in self) } $ident);
28 };
29 (pub $ident:ident) => {
30 custom_keyword_internal!({ pub } $ident);
31 };
32 (pub(crate) $ident:ident) => {
33 custom_keyword_internal!({ pub(crate) } $ident);
34 };
35 (pub(super) $ident:ident) => {
36 custom_keyword_internal!({ pub(super) } $ident);
37 };
38 (pub(self) $ident:ident) => {
39 custom_keyword_internal!({ pub(self) } $ident);
40 };
41 (pub(in $path:path) $ident:ident) => {
42 custom_keyword_internal!({ pub(in $path) } $ident);
43 };
44}
45
46#[macro_export]
47#[doc(hidden)]
48macro_rules! custom_keyword_internal {
49 ({ $($vis:tt)* } $ident:ident) => {
50 $($vis)* struct $ident {
51 inner: $crate::Ident
52 }
53
54 impl $crate::parse::Keyword for $ident {
55 fn ident() -> &'static str {
56 stringify!($ident)
57 }
58
59 fn display() -> &'static str {
60 concat!("`", stringify!($ident), "`")
61 }
62 }
63
64 impl $crate::parse::Parse for $ident {
65 fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> {
66 input.step(|cursor| {
67 if let Some((ident, rest)) = cursor.ident() {
68 if ident == stringify!($ident) {
69 return Ok(($ident { inner: ident }, rest));
70 }
71 }
72 Err(cursor.error(concat!("expected `", stringify!($ident), "`")))
73 })
74 }
75 }
76
77 $($vis)* fn $ident(marker: $crate::parse::TokenMarker) -> $ident {
78 match marker {}
79 }
80 }
81}