@@ -34,28 +34,28 @@ enum Def<'a> {
34
34
35
35
/// A symbol, either a leaf or with modifiers with optional deprecation.
36
36
enum Symbol < ' a > {
37
- Single ( char ) ,
38
- Multi ( Vec < ( ModifierSet < & ' a str > , char , Option < & ' a str > ) > ) ,
37
+ Single ( String ) ,
38
+ Multi ( Vec < ( ModifierSet < & ' a str > , String , Option < & ' a str > ) > ) ,
39
39
}
40
40
41
41
/// A single line during parsing.
42
- #[ derive( Debug , Copy , Clone ) ]
42
+ #[ derive( Debug , Clone ) ]
43
43
enum Line < ' a > {
44
44
Blank ,
45
45
Deprecated ( & ' a str ) ,
46
46
ModuleStart ( & ' a str ) ,
47
47
ModuleEnd ,
48
- Symbol ( & ' a str , Option < char > ) ,
49
- Variant ( ModifierSet < & ' a str > , char ) ,
48
+ Symbol ( & ' a str , Option < String > ) ,
49
+ Variant ( ModifierSet < & ' a str > , String ) ,
50
50
Eof ,
51
51
}
52
52
53
- #[ derive( Debug , Copy , Clone ) ]
53
+ #[ derive( Debug , Clone ) ]
54
54
enum Declaration < ' a > {
55
55
ModuleStart ( & ' a str , Option < & ' a str > ) ,
56
56
ModuleEnd ,
57
- Symbol ( & ' a str , Option < char > , Option < & ' a str > ) ,
58
- Variant ( ModifierSet < & ' a str > , char , Option < & ' a str > ) ,
57
+ Symbol ( & ' a str , Option < String > , Option < & ' a str > ) ,
58
+ Variant ( ModifierSet < & ' a str > , String , Option < & ' a str > ) ,
59
59
}
60
60
61
61
fn main ( ) {
@@ -103,11 +103,11 @@ fn process(buf: &mut String, file: &Path, name: &str, desc: &str) {
103
103
Some ( Ok ( Declaration :: ModuleEnd ) )
104
104
}
105
105
}
106
- Ok ( Line :: Symbol ( name, c ) ) => {
107
- Some ( Ok ( Declaration :: Symbol ( name, c , deprecation. take ( ) ) ) )
106
+ Ok ( Line :: Symbol ( name, value ) ) => {
107
+ Some ( Ok ( Declaration :: Symbol ( name, value , deprecation. take ( ) ) ) )
108
108
}
109
- Ok ( Line :: Variant ( modifiers, c ) ) => {
110
- Some ( Ok ( Declaration :: Variant ( modifiers, c , deprecation. take ( ) ) ) )
109
+ Ok ( Line :: Variant ( modifiers, value ) ) => {
110
+ Some ( Ok ( Declaration :: Variant ( modifiers, value , deprecation. take ( ) ) ) )
111
111
}
112
112
Ok ( Line :: Eof ) => {
113
113
deprecation. map ( |_| Err ( String :: from ( "dangling `@deprecated:`" ) ) )
@@ -156,12 +156,12 @@ fn tokenize(line: &str) -> StrResult<Line> {
156
156
for part in rest. split ( '.' ) {
157
157
validate_ident ( part) ?;
158
158
}
159
- let c = decode_char ( tail. ok_or ( "missing char" ) ?) ?;
160
- Line :: Variant ( ModifierSet :: from_raw_dotted ( rest) , c )
159
+ let value = decode_value ( tail. ok_or ( "missing char" ) ?) ?;
160
+ Line :: Variant ( ModifierSet :: from_raw_dotted ( rest) , value )
161
161
} else {
162
162
validate_ident ( head) ?;
163
- let c = tail. map ( decode_char ) . transpose ( ) ?;
164
- Line :: Symbol ( head, c )
163
+ let value = tail. map ( decode_value ) . transpose ( ) ?;
164
+ Line :: Symbol ( head, value )
165
165
} )
166
166
}
167
167
@@ -174,20 +174,23 @@ fn validate_ident(string: &str) -> StrResult<()> {
174
174
Err ( format ! ( "invalid identifier: {string:?}" ) )
175
175
}
176
176
177
- /// Extracts either a single char or parses a U+XXXX escape.
178
- fn decode_char ( text : & str ) -> StrResult < char > {
179
- if let Some ( hex) = text. strip_prefix ( "U+" ) {
180
- u32:: from_str_radix ( hex, 16 )
181
- . ok ( )
182
- . and_then ( |n| char:: try_from ( n) . ok ( ) )
183
- . ok_or_else ( || format ! ( "invalid unicode escape {text:?}" ) )
184
- } else {
185
- let mut chars = text. chars ( ) ;
186
- match ( chars. next ( ) , chars. next ( ) ) {
187
- ( Some ( c) , None ) => Ok ( c) ,
188
- _ => Err ( format ! ( "expected exactly one char, found {text:?}" ) ) ,
189
- }
177
+ /// Extracts the value of a variant, parsing `\u{XXXX}` escapes
178
+ fn decode_value ( text : & str ) -> StrResult < String > {
179
+ let mut iter = text. split ( "\\ u{" ) ;
180
+ let mut res = iter. next ( ) . unwrap ( ) . to_string ( ) ;
181
+ for other in iter {
182
+ let ( hex, rest) = other. split_once ( "}" ) . ok_or_else ( || {
183
+ format ! ( "unclosed unicode escape \\ u{{{}" , other. escape_debug( ) )
184
+ } ) ?;
185
+ res. push (
186
+ u32:: from_str_radix ( hex, 16 )
187
+ . ok ( )
188
+ . and_then ( |n| char:: try_from ( n) . ok ( ) )
189
+ . ok_or_else ( || format ! ( "invalid unicode escape \\ u{{{hex}}}" ) ) ?,
190
+ ) ;
191
+ res += rest;
190
192
}
193
+ Ok ( res)
191
194
}
192
195
193
196
/// Turns a stream of lines into a list of definitions.
@@ -200,23 +203,23 @@ fn parse<'a>(
200
203
None | Some ( Declaration :: ModuleEnd ) => {
201
204
break ;
202
205
}
203
- Some ( Declaration :: Symbol ( name, c , deprecation) ) => {
206
+ Some ( Declaration :: Symbol ( name, value , deprecation) ) => {
204
207
let mut variants = vec ! [ ] ;
205
- while let Some ( Declaration :: Variant ( name, c , deprecation) ) =
208
+ while let Some ( Declaration :: Variant ( name, value , deprecation) ) =
206
209
p. peek ( ) . cloned ( ) . transpose ( ) ?
207
210
{
208
- variants. push ( ( name, c , deprecation) ) ;
211
+ variants. push ( ( name, value , deprecation) ) ;
209
212
p. next ( ) ;
210
213
}
211
214
212
215
let symbol = if !variants. is_empty ( ) {
213
- if let Some ( c ) = c {
214
- variants. insert ( 0 , ( ModifierSet :: default ( ) , c , None ) ) ;
216
+ if let Some ( value ) = value {
217
+ variants. insert ( 0 , ( ModifierSet :: default ( ) , value , None ) ) ;
215
218
}
216
219
Symbol :: Multi ( variants)
217
220
} else {
218
- let c = c . ok_or ( "symbol needs char or variants" ) ?;
219
- Symbol :: Single ( c )
221
+ let value = value . ok_or ( "symbol needs char or variants" ) ?;
222
+ Symbol :: Single ( value )
220
223
} ;
221
224
222
225
defs. push ( ( name, Binding { def : Def :: Symbol ( symbol) , deprecation } ) ) ;
@@ -251,7 +254,7 @@ fn encode(buf: &mut String, module: &Module) {
251
254
Def :: Symbol ( symbol) => {
252
255
buf. push_str ( "Def::Symbol(Symbol::" ) ;
253
256
match symbol {
254
- Symbol :: Single ( c ) => write ! ( buf, "Single({c :?})" ) . unwrap ( ) ,
257
+ Symbol :: Single ( value ) => write ! ( buf, "Single({value :?})" ) . unwrap ( ) ,
255
258
Symbol :: Multi ( list) => write ! ( buf, "Multi(&{list:?})" ) . unwrap ( ) ,
256
259
}
257
260
buf. push ( ')' ) ;
0 commit comments