@@ -19,12 +19,30 @@ pub enum Token {
19
19
Null ,
20
20
}
21
21
22
+ impl Token {
23
+ pub fn to_string ( & self ) -> String {
24
+ match * self {
25
+ Token :: Comma => "," ,
26
+ Token :: Colon => ":" ,
27
+ Token :: BracketOn => "[" ,
28
+ Token :: BracketOff => "]" ,
29
+ Token :: BraceOn => "{" ,
30
+ Token :: BraceOff => "}" ,
31
+ Token :: String ( _) => "[string]" ,
32
+ Token :: Number ( _) => "[number]" ,
33
+ Token :: Boolean ( true ) => "true" ,
34
+ Token :: Boolean ( false ) => "false" ,
35
+ Token :: Null => "null" ,
36
+ } . into ( )
37
+ }
38
+ }
39
+
22
40
macro_rules! sequence {
23
41
( $tok: ident, $( $ch: pat ) ,* ) => {
24
42
$(
25
43
match $tok. next_byte( ) {
26
44
Some ( $ch) => { } ,
27
- Some ( ch) => return Err ( JsonError :: unexpected_character ( ch) ) ,
45
+ Some ( ch) => return Err ( $tok . unexpected_character_error ( ch) ) ,
28
46
None => return Err ( JsonError :: UnexpectedEndOfJson )
29
47
}
30
48
) *
@@ -48,8 +66,14 @@ macro_rules! read_num {
48
66
}
49
67
}
50
68
69
+ struct Position {
70
+ pub line : usize ,
71
+ pub column : usize ,
72
+ }
73
+
51
74
struct Tokenizer < ' a > {
52
- source : Enumerate < Bytes < ' a > > ,
75
+ source : & ' a str ,
76
+ byte_iter : Enumerate < Bytes < ' a > > ,
53
77
buffer : Vec < u8 > ,
54
78
left_over : Option < u8 > ,
55
79
current_index : usize ,
@@ -58,16 +82,39 @@ struct Tokenizer<'a> {
58
82
impl < ' a > Tokenizer < ' a > {
59
83
pub fn new ( source : & ' a str ) -> Self {
60
84
Tokenizer {
61
- source : source. bytes ( ) . enumerate ( ) ,
85
+ source : source,
86
+ byte_iter : source. bytes ( ) . enumerate ( ) ,
62
87
buffer : Vec :: with_capacity ( 512 ) ,
63
88
left_over : None ,
64
89
current_index : 0 ,
65
90
}
66
91
}
67
92
93
+ pub fn source_position_from_index ( & self , index : usize ) -> Position {
94
+ let ( bytes, _) = self . source . split_at ( index) ;
95
+
96
+ Position {
97
+ line : bytes. lines ( ) . count ( ) ,
98
+ column : bytes. lines ( ) . last ( ) . map ( |line| {
99
+ line. chars ( ) . count ( ) + 1
100
+ } ) . unwrap_or ( 1 )
101
+ }
102
+ }
103
+
104
+ fn unexpected_character_error ( & self , byte : u8 ) -> JsonError {
105
+ let pos = self . source_position_from_index ( self . current_index ) ;
106
+ let ch = char:: from_u32 ( byte as u32 ) . unwrap_or ( '?' ) ;
107
+
108
+ JsonError :: UnexpectedCharacter {
109
+ ch : ch,
110
+ line : pos. line ,
111
+ column : pos. column ,
112
+ }
113
+ }
114
+
68
115
#[ inline( always) ]
69
116
fn next_byte ( & mut self ) -> Option < u8 > {
70
- self . source . next ( ) . map ( |( index, byte) | {
117
+ self . byte_iter . next ( ) . map ( |( index, byte) | {
71
118
self . current_index = index;
72
119
byte
73
120
} )
@@ -109,7 +156,7 @@ impl<'a> Tokenizer<'a> {
109
156
b'0' ... b'9' => ( ch - b'0' ) as u32 ,
110
157
b'a' ... b'f' => ( ch + 10 - b'a' ) as u32 ,
111
158
b'A' ... b'F' => ( ch + 10 - b'A' ) as u32 ,
112
- ch => return Err ( JsonError :: unexpected_character ( ch) ) ,
159
+ ch => return Err ( self . unexpected_character_error ( ch) ) ,
113
160
} )
114
161
}
115
162
@@ -219,10 +266,12 @@ impl<'a> Tokenizer<'a> {
219
266
Ok ( if first == b'-' { num * -1.0 } else { num } )
220
267
}
221
268
222
- fn next ( & mut self ) -> JsonResult < Token > {
269
+ fn next ( & mut self ) -> JsonResult < ( usize , Token ) > {
223
270
loop {
224
271
let ch = try!( self . checked_expect_byte ( ) ) ;
225
- return Ok ( match ch {
272
+ let index = self . current_index ;
273
+
274
+ return Ok ( ( index, match ch {
226
275
b',' => Token :: Comma ,
227
276
b':' => Token :: Colon ,
228
277
b'[' => Token :: BracketOn ,
@@ -245,25 +294,29 @@ impl<'a> Tokenizer<'a> {
245
294
} ,
246
295
// whitespace
247
296
9 ... 13 | 32 | 133 | 160 => continue ,
248
- _ => return Err ( JsonError :: unexpected_character ( ch) )
249
- } ) ;
297
+ _ => return Err ( self . unexpected_character_error ( ch) )
298
+ } ) ) ;
250
299
}
251
300
}
252
301
}
253
302
254
303
macro_rules! expect {
255
304
( $parser: ident, $token: pat => $value: ident) => (
256
305
match $parser. tokenizer. next( ) {
257
- Ok ( $token) => $value,
258
- Ok ( token) => return Err ( JsonError :: unexpected_token( token) ) ,
259
- Err ( error) => return Err ( error) ,
306
+ Ok ( ( _, $token) ) => $value,
307
+ Ok ( ( index, token) ) => {
308
+ return Err ( $parser. unexpected_token_error( index, token) ) ;
309
+ } ,
310
+ Err ( error) => return Err ( error) ,
260
311
}
261
312
) ;
262
313
( $parser: ident, $token: pat) => ( {
263
314
match $parser. tokenizer. next( ) {
264
- Ok ( $token) => { } ,
265
- Ok ( token) => return Err ( JsonError :: unexpected_token( token) ) ,
266
- Err ( error) => return Err ( error) ,
315
+ Ok ( ( _, $token) ) => { } ,
316
+ Ok ( ( index, token) ) => {
317
+ return Err ( $parser. unexpected_token_error( index, token) ) ;
318
+ } ,
319
+ Err ( error) => return Err ( error) ,
267
320
}
268
321
} )
269
322
}
@@ -279,10 +332,20 @@ impl<'a> Parser<'a> {
279
332
}
280
333
}
281
334
335
+ fn unexpected_token_error ( & self , index : usize , token : Token ) -> JsonError {
336
+ let pos = self . tokenizer . source_position_from_index ( index) ;
337
+
338
+ JsonError :: UnexpectedToken {
339
+ token : token. to_string ( ) ,
340
+ line : pos. line ,
341
+ column : pos. column ,
342
+ }
343
+ }
344
+
282
345
#[ must_use]
283
346
fn ensure_end ( & mut self ) -> JsonResult < ( ) > {
284
347
match self . tokenizer . next ( ) {
285
- Ok ( token) => Err ( JsonError :: unexpected_token ( token) ) ,
348
+ Ok ( ( index , token) ) => Err ( self . unexpected_token_error ( index , token) ) ,
286
349
Err ( JsonError :: UnexpectedEndOfJson ) => Ok ( ( ) ) ,
287
350
Err ( error) => Err ( error)
288
351
}
@@ -292,18 +355,22 @@ impl<'a> Parser<'a> {
292
355
let mut array = Vec :: with_capacity ( 20 ) ;
293
356
294
357
match try!( self . tokenizer . next ( ) ) {
295
- Token :: BracketOff => return Ok ( JsonValue :: Array ( array) ) ,
296
- token => array. push ( try!( self . value_from ( token) ) ) ,
358
+ ( _, Token :: BracketOff ) => return Ok ( JsonValue :: Array ( array) ) ,
359
+ ( index, token) => {
360
+ array. push ( try!( self . value_from ( index, token) ) ) ;
361
+ }
297
362
}
298
363
299
364
loop {
300
365
match try!( self . tokenizer . next ( ) ) {
301
- Token :: Comma => {
366
+ ( _ , Token :: Comma ) => {
302
367
array. push ( try!( self . value ( ) ) ) ;
303
368
continue
304
369
} ,
305
- Token :: BracketOff => break ,
306
- token => return Err ( JsonError :: unexpected_token ( token) )
370
+ ( _, Token :: BracketOff ) => break ,
371
+ ( index, token) => {
372
+ return Err ( self . unexpected_token_error ( index, token) )
373
+ }
307
374
}
308
375
}
309
376
@@ -314,49 +381,53 @@ impl<'a> Parser<'a> {
314
381
let mut object = BTreeMap :: new ( ) ;
315
382
316
383
match try!( self . tokenizer . next ( ) ) {
317
- Token :: BraceOff => return Ok ( JsonValue :: Object ( object) ) ,
318
- Token :: String ( key) => {
384
+ ( _ , Token :: BraceOff ) => return Ok ( JsonValue :: Object ( object) ) ,
385
+ ( _ , Token :: String ( key) ) => {
319
386
expect ! ( self , Token :: Colon ) ;
320
387
object. insert ( key, try!( self . value ( ) ) ) ;
321
388
} ,
322
- token => return Err ( JsonError :: unexpected_token ( token) )
389
+ ( index, token) => {
390
+ return Err ( self . unexpected_token_error ( index, token) )
391
+ }
323
392
}
324
393
325
394
loop {
326
395
match try!( self . tokenizer . next ( ) ) {
327
- Token :: Comma => {
396
+ ( _ , Token :: Comma ) => {
328
397
let key = expect ! ( self ,
329
398
Token :: String ( key) => key
330
399
) ;
331
400
expect ! ( self , Token :: Colon ) ;
332
401
object. insert ( key, try!( self . value ( ) ) ) ;
333
402
continue
334
403
} ,
335
- Token :: BraceOff => break ,
336
- token => return Err ( JsonError :: unexpected_token ( token) )
404
+ ( _, Token :: BraceOff ) => break ,
405
+ ( index, token) => {
406
+ return Err ( self . unexpected_token_error ( index, token) )
407
+ }
337
408
}
338
409
}
339
410
340
411
Ok ( JsonValue :: Object ( object) )
341
412
}
342
413
343
- fn value_from ( & mut self , token : Token ) -> JsonResult < JsonValue > {
414
+ fn value_from ( & mut self , index : usize , token : Token ) -> JsonResult < JsonValue > {
344
415
Ok ( match token {
345
416
Token :: String ( value) => JsonValue :: String ( value) ,
346
417
Token :: Number ( value) => JsonValue :: Number ( value) ,
347
418
Token :: Boolean ( value) => JsonValue :: Boolean ( value) ,
348
419
Token :: Null => JsonValue :: Null ,
349
420
Token :: BracketOn => return self . array ( ) ,
350
421
Token :: BraceOn => return self . object ( ) ,
351
- token => {
352
- return Err ( JsonError :: unexpected_token ( token) )
422
+ _ => {
423
+ return Err ( self . unexpected_token_error ( index , token) )
353
424
}
354
425
} )
355
426
}
356
427
357
428
fn value ( & mut self ) -> JsonResult < JsonValue > {
358
- let token = try!( self . tokenizer . next ( ) ) ;
359
- self . value_from ( token)
429
+ let ( index , token) = try!( self . tokenizer . next ( ) ) ;
430
+ self . value_from ( index , token)
360
431
}
361
432
}
362
433
0 commit comments