@@ -16,15 +16,19 @@ pub enum Error {
16
16
Eof ,
17
17
}
18
18
19
- type Result < ' a , T > = std:: result:: Result < T , Error > ;
19
+ type Result < T > = std:: result:: Result < T , Error > ;
20
20
21
21
impl < ' a > Parser < ' a > {
22
22
fn new ( cursor : & ' a str ) -> Self {
23
23
Self { cursor }
24
24
}
25
25
26
26
fn peek ( & self , c : char ) -> bool {
27
- self . cursor . chars ( ) . next ( ) == Some ( c)
27
+ self . peek_next ( ) == Some ( c)
28
+ }
29
+
30
+ fn eof ( & self ) -> bool {
31
+ self . cursor . is_empty ( )
28
32
}
29
33
30
34
fn peek_next ( & self ) -> Option < char > {
@@ -104,46 +108,39 @@ impl<'a> Parser<'a> {
104
108
}
105
109
}
106
110
107
- fn dict ( & mut self ) -> Result < Dict > {
108
- self . eat ( '{' ) ?;
111
+ fn delimited < T , V , F > ( & mut self , start : char , end : char , value : F ) -> Result < T >
112
+ where T : Extend < V > + Default , F : Fn ( & mut Self ) -> Result < V > ,
113
+ {
114
+ let mut collection = T :: default ( ) ;
115
+ self . eat ( start) ?;
116
+ self . skip_whitespace ( ) ;
117
+
118
+ while !self . peek ( end) {
119
+ collection. extend ( Some ( value ( self ) ?) ) ;
109
120
110
- let mut dict = Dict :: new ( ) ;
111
- loop {
112
121
self . skip_whitespace ( ) ;
113
- if self . eat ( '} ' ) . is_ok ( ) {
122
+ if self . eat ( ', ' ) . is_err ( ) {
114
123
break ;
115
124
}
116
125
117
- let key = self . key ( ) ?;
118
126
self . skip_whitespace ( ) ;
119
- self . eat ( '=' ) ?;
120
- self . skip_whitespace ( ) ;
121
- let value = self . value ( ) ?;
122
- dict. insert ( key. to_string ( ) , value) ;
123
-
124
- self . skip_whitespace ( ) ;
125
- let _ = self . eat ( ',' ) ;
126
127
}
127
128
128
- Ok ( dict)
129
+ self . eat ( end) ?;
130
+ Ok ( collection)
129
131
}
130
132
131
- fn array ( & mut self ) -> Result < Vec < Value > > {
132
- self . eat ( '[' ) ?;
133
- let mut values = Vec :: new ( ) ;
134
-
135
- loop {
136
- self . skip_whitespace ( ) ;
137
- if self . eat ( ']' ) . is_ok ( ) {
138
- break ;
139
- }
140
-
141
- values. push ( self . value ( ) ?) ;
142
- self . skip_whitespace ( ) ;
143
- let _ = self . eat ( ',' ) ;
144
- }
133
+ fn dict ( & mut self ) -> Result < Dict > {
134
+ self . delimited ( '{' , '}' , |parser| {
135
+ let key = parser. key ( ) ?;
136
+ ( parser. skip_whitespace ( ) , parser. eat ( '=' ) ?, parser. skip_whitespace ( ) ) ;
137
+ let value = parser. value ( ) ?;
138
+ Ok ( ( key. to_string ( ) , value) )
139
+ } )
140
+ }
145
141
146
- Ok ( values)
142
+ fn array ( & mut self ) -> Result < Vec < Value > > {
143
+ self . delimited ( '[' , ']' , |parser| parser. value ( ) )
147
144
}
148
145
149
146
fn value ( & mut self ) -> Result < Value > {
@@ -152,6 +149,7 @@ impl<'a> Parser<'a> {
152
149
!matches ! ( byte, ',' | '{' | '}' | '[' | ']' )
153
150
}
154
151
152
+ self . skip_whitespace ( ) ;
155
153
let value = match self . peek_next ( ) {
156
154
Some ( '"' ) => Value :: from ( self . quoted_str ( ) ?. to_string ( ) ) ,
157
155
Some ( '\'' ) => Value :: from ( self . quoted_char ( ) ?) ,
@@ -187,11 +185,12 @@ impl<'a> Parser<'a> {
187
185
impl std:: str:: FromStr for Value {
188
186
type Err = std:: convert:: Infallible ;
189
187
190
- fn from_str ( s : & str ) -> std:: result:: Result < Self , std:: convert:: Infallible > {
191
- let mut parser = Parser :: new ( s. trim ( ) ) ;
188
+ fn from_str ( string : & str ) -> std:: result:: Result < Self , std:: convert:: Infallible > {
189
+ let string = string. trim ( ) ;
190
+ let mut parser = Parser :: new ( string) ;
192
191
match parser. value ( ) {
193
- Ok ( value) => Ok ( value) ,
194
- Err ( _ ) => Ok ( Value :: from ( s ) ) ,
192
+ Ok ( value) if parser . eof ( ) => Ok ( value) ,
193
+ _ => Ok ( Value :: from ( string ) ) ,
195
194
}
196
195
}
197
196
}
@@ -231,13 +230,19 @@ mod tests {
231
230
" -0" => 0i8 ,
232
231
" -2" => -2 ,
233
232
" 123 " => 123u8 ,
233
+ "a,b" => "a,b" ,
234
+ " a,b" => "a,b" ,
234
235
"\" a\" " => "a" ,
235
236
"a " => "a" ,
236
237
" a " => "a" ,
237
238
"\" a\" " => " a" ,
238
239
"\" a \" " => "a " ,
239
240
"\" a \" " => " a " ,
240
241
"1.2" => 1.2 ,
242
+ "[" => "[" ,
243
+ "[a" => "[a" ,
244
+ "[a b" => "[a b" ,
245
+ "]" => "]" ,
241
246
" 1.2" => 1.2 ,
242
247
"3.14159" => 3.14159 ,
243
248
"\" \\ t\" " => "\t " ,
@@ -263,6 +268,9 @@ mod tests {
263
268
"[1,2,3]" => vec![ 1u8 , 2u8 , 3u8 ] ,
264
269
"[ 1 , 2 ,3]" => vec![ 1u8 , 2u8 , 3u8 ] ,
265
270
" [ 1 , 2 , 3 ] " => vec![ 1u8 , 2u8 , 3u8 ] ,
271
+ " [ a , b ,, d ] " => vec![ "a" , "b" , "" , "d" ] ,
272
+ " [ a , b c,] " => vec![ "a" , "b c" ] ,
273
+ " [ a , b c,,] " => vec![ "a" , "b c" , "" ] ,
266
274
"{a=b}" => map![ "a" => "b" ] ,
267
275
" { a = b } " => map![ "a" => "b" ] ,
268
276
"{\" a\" =b}" => map![ "a" => "b" ] ,
0 commit comments