Make TokenType::from_u32
foolproof.
Currently it relies on having the right integer for every variant, and if you add a variant you need to adjust the integers for all subsequent variants, which is a pain. This commit introduces a match guard formulation that takes advantage of the enum-to-integer conversion to avoid specifying the integer for each variant. And it does this via a macro to avoid lots of boilerplate.
This commit is contained in:
parent
b9bf0b4b10
commit
df56c50cee
1 changed files with 121 additions and 110 deletions
|
@ -145,124 +145,135 @@ pub enum TokenType {
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Macro to avoid repetitive boilerplate code.
|
||||||
|
macro_rules! from_u32_match {
|
||||||
|
($val:ident; $($tok:ident,)+) => {
|
||||||
|
// A more obvious formulation would be `0 => TokenType::Eq`. But
|
||||||
|
// this formulation with the guard lets us avoid specifying a
|
||||||
|
// specific integer for each variant.
|
||||||
|
match $val {
|
||||||
|
$(
|
||||||
|
t if t == TokenType::$tok as u32 => TokenType::$tok,
|
||||||
|
)+
|
||||||
|
_ => panic!("unhandled value: {}", $val),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl TokenType {
|
impl TokenType {
|
||||||
fn from_u32(val: u32) -> TokenType {
|
fn from_u32(val: u32) -> TokenType {
|
||||||
let token_type = match val {
|
let token_type = from_u32_match! { val;
|
||||||
0 => TokenType::Eq,
|
Eq,
|
||||||
1 => TokenType::Lt,
|
Lt,
|
||||||
2 => TokenType::Le,
|
Le,
|
||||||
3 => TokenType::EqEq,
|
EqEq,
|
||||||
4 => TokenType::Gt,
|
Gt,
|
||||||
5 => TokenType::AndAnd,
|
AndAnd,
|
||||||
6 => TokenType::OrOr,
|
OrOr,
|
||||||
7 => TokenType::Not,
|
Not,
|
||||||
8 => TokenType::Tilde,
|
Tilde,
|
||||||
|
|
||||||
9 => TokenType::Plus,
|
Plus,
|
||||||
10 => TokenType::Minus,
|
Minus,
|
||||||
11 => TokenType::Star,
|
Star,
|
||||||
12 => TokenType::And,
|
And,
|
||||||
13 => TokenType::Or,
|
Or,
|
||||||
|
|
||||||
14 => TokenType::At,
|
At,
|
||||||
15 => TokenType::Dot,
|
Dot,
|
||||||
16 => TokenType::DotDot,
|
DotDot,
|
||||||
17 => TokenType::DotDotDot,
|
DotDotDot,
|
||||||
18 => TokenType::DotDotEq,
|
DotDotEq,
|
||||||
19 => TokenType::Comma,
|
Comma,
|
||||||
20 => TokenType::Semi,
|
Semi,
|
||||||
21 => TokenType::Colon,
|
Colon,
|
||||||
22 => TokenType::PathSep,
|
PathSep,
|
||||||
23 => TokenType::RArrow,
|
RArrow,
|
||||||
24 => TokenType::FatArrow,
|
FatArrow,
|
||||||
25 => TokenType::Pound,
|
Pound,
|
||||||
26 => TokenType::Question,
|
Question,
|
||||||
27 => TokenType::OpenParen,
|
OpenParen,
|
||||||
28 => TokenType::CloseParen,
|
CloseParen,
|
||||||
29 => TokenType::OpenBrace,
|
OpenBrace,
|
||||||
30 => TokenType::CloseBrace,
|
CloseBrace,
|
||||||
31 => TokenType::OpenBracket,
|
OpenBracket,
|
||||||
32 => TokenType::CloseBracket,
|
CloseBracket,
|
||||||
33 => TokenType::Eof,
|
Eof,
|
||||||
|
|
||||||
34 => TokenType::Operator,
|
Operator,
|
||||||
35 => TokenType::Ident,
|
Ident,
|
||||||
36 => TokenType::Lifetime,
|
Lifetime,
|
||||||
37 => TokenType::Path,
|
Path,
|
||||||
38 => TokenType::Type,
|
Type,
|
||||||
39 => TokenType::Const,
|
Const,
|
||||||
|
|
||||||
40 => TokenType::KwAs,
|
KwAs,
|
||||||
41 => TokenType::KwAsync,
|
KwAsync,
|
||||||
42 => TokenType::KwAuto,
|
KwAuto,
|
||||||
43 => TokenType::KwAwait,
|
KwAwait,
|
||||||
44 => TokenType::KwBecome,
|
KwBecome,
|
||||||
45 => TokenType::KwBox,
|
KwBox,
|
||||||
46 => TokenType::KwBreak,
|
KwBreak,
|
||||||
47 => TokenType::KwCatch,
|
KwCatch,
|
||||||
48 => TokenType::KwConst,
|
KwConst,
|
||||||
49 => TokenType::KwContinue,
|
KwContinue,
|
||||||
50 => TokenType::KwCrate,
|
KwCrate,
|
||||||
51 => TokenType::KwDefault,
|
KwDefault,
|
||||||
52 => TokenType::KwDyn,
|
KwDyn,
|
||||||
53 => TokenType::KwElse,
|
KwElse,
|
||||||
54 => TokenType::KwEnum,
|
KwEnum,
|
||||||
55 => TokenType::KwExtern,
|
KwExtern,
|
||||||
56 => TokenType::KwFn,
|
KwFn,
|
||||||
57 => TokenType::KwFor,
|
KwFor,
|
||||||
58 => TokenType::KwGen,
|
KwGen,
|
||||||
59 => TokenType::KwIf,
|
KwIf,
|
||||||
60 => TokenType::KwImpl,
|
KwImpl,
|
||||||
61 => TokenType::KwIn,
|
KwIn,
|
||||||
62 => TokenType::KwLet,
|
KwLet,
|
||||||
63 => TokenType::KwLoop,
|
KwLoop,
|
||||||
64 => TokenType::KwMacro,
|
KwMacro,
|
||||||
65 => TokenType::KwMacroRules,
|
KwMacroRules,
|
||||||
66 => TokenType::KwMatch,
|
KwMatch,
|
||||||
67 => TokenType::KwMod,
|
KwMod,
|
||||||
68 => TokenType::KwMove,
|
KwMove,
|
||||||
69 => TokenType::KwMut,
|
KwMut,
|
||||||
70 => TokenType::KwPub,
|
KwPub,
|
||||||
71 => TokenType::KwRaw,
|
KwRaw,
|
||||||
72 => TokenType::KwRef,
|
KwRef,
|
||||||
73 => TokenType::KwReturn,
|
KwReturn,
|
||||||
74 => TokenType::KwReuse,
|
KwReuse,
|
||||||
75 => TokenType::KwSafe,
|
KwSafe,
|
||||||
76 => TokenType::KwSelfUpper,
|
KwSelfUpper,
|
||||||
77 => TokenType::KwStatic,
|
KwStatic,
|
||||||
78 => TokenType::KwStruct,
|
KwStruct,
|
||||||
79 => TokenType::KwTrait,
|
KwTrait,
|
||||||
80 => TokenType::KwTry,
|
KwTry,
|
||||||
81 => TokenType::KwType,
|
KwType,
|
||||||
82 => TokenType::KwUnderscore,
|
KwUnderscore,
|
||||||
83 => TokenType::KwUnsafe,
|
KwUnsafe,
|
||||||
84 => TokenType::KwUse,
|
KwUse,
|
||||||
85 => TokenType::KwWhere,
|
KwWhere,
|
||||||
86 => TokenType::KwWhile,
|
KwWhile,
|
||||||
87 => TokenType::KwYield,
|
KwYield,
|
||||||
|
|
||||||
88 => TokenType::SymAttSyntax,
|
SymAttSyntax,
|
||||||
89 => TokenType::SymClobberAbi,
|
SymClobberAbi,
|
||||||
90 => TokenType::SymInlateout,
|
SymInlateout,
|
||||||
91 => TokenType::SymInout,
|
SymInout,
|
||||||
92 => TokenType::SymIs,
|
SymIs,
|
||||||
93 => TokenType::SymLabel,
|
SymLabel,
|
||||||
94 => TokenType::SymLateout,
|
SymLateout,
|
||||||
95 => TokenType::SymMayUnwind,
|
SymMayUnwind,
|
||||||
96 => TokenType::SymNomem,
|
SymNomem,
|
||||||
97 => TokenType::SymNoreturn,
|
SymNoreturn,
|
||||||
98 => TokenType::SymNostack,
|
SymNostack,
|
||||||
99 => TokenType::SymOptions,
|
SymOptions,
|
||||||
100 => TokenType::SymOut,
|
SymOut,
|
||||||
101 => TokenType::SymPreservesFlags,
|
SymPreservesFlags,
|
||||||
102 => TokenType::SymPure,
|
SymPure,
|
||||||
103 => TokenType::SymReadonly,
|
SymReadonly,
|
||||||
104 => TokenType::SymSym,
|
SymSym,
|
||||||
|
|
||||||
_ => panic!("unhandled value: {val}"),
|
|
||||||
};
|
};
|
||||||
// This assertion will detect if this method and the type definition get out of sync.
|
|
||||||
assert_eq!(token_type as u32, val);
|
|
||||||
token_type
|
token_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue