@@ -231,6 +231,32 @@ pub fn symbol_parser(input: &str) -> IResult<&str, Symbol> {
231
231
}
232
232
}
233
233
234
+ pub fn string_parser ( input : & str ) -> IResult < & str , String > {
235
+ // Convert escaped characters like \n to their actual counterparts -- like an actual newline
236
+ named ! ( escaped_string_parser<& str , String >, escaped_transform!( take_till1!( |ch| { ch == '\\' || ch == '\"' } ) , '\\' , alt!(
237
+ tag!( "t" ) => { |_| "\t " } |
238
+ tag!( "b" ) => { |_| "\x08 " } |
239
+ tag!( "n" ) => { |_| "\n " } |
240
+ tag!( "r" ) => { |_| "\r " } |
241
+ tag!( "f" ) => { |_| "\x0C " } |
242
+ tag!( "'" ) => { |_| "'" } |
243
+ tag!( "\" " ) => { |_| "\" " } |
244
+ tag!( "\\ " ) => { |_| "\\ " }
245
+ ) ) ) ;
246
+
247
+ named ! ( empty_string_parser <& str , String >, map!( tag!( "\" \" " ) , |_| String :: from( "" ) ) ) ;
248
+
249
+ named ! (
250
+ string_parser<& str , String >,
251
+ alt!(
252
+ delimited!( tag( "\" " ) , escaped_string_parser, tag( "\" " ) ) |
253
+ // Base case; empty string
254
+ empty_string_parser)
255
+ ) ;
256
+
257
+ string_parser ( input)
258
+ }
259
+
234
260
// Helper function to integer_parser for same reason as
235
261
// identifier_tail. See comment above said function for explanation
236
262
@@ -375,52 +401,18 @@ pub fn try_read_nil(input: &str) -> IResult<&str, Value> {
375
401
/// Example Successes:
376
402
/// "this is pretty straightforward" => Value::String("this is pretty straightforward")
377
403
pub fn try_read_string ( input : & str ) -> IResult < & str , Value > {
378
- // Convert escaped characters like \n to their actual counterparts -- like an actual newline
379
- named ! ( escaped_string_parser<& str , String >, escaped_transform!( take_till1!( |ch| { ch == '\\' || ch == '\"' } ) , '\\' , alt!(
380
- tag!( "t" ) => { |_| "\t " } |
381
- tag!( "b" ) => { |_| "\x08 " } |
382
- tag!( "n" ) => { |_| "\n " } |
383
- tag!( "r" ) => { |_| "\r " } |
384
- tag!( "f" ) => { |_| "\x0C " } |
385
- tag!( "'" ) => { |_| "'" } |
386
- tag!( "\" " ) => { |_| "\" " } |
387
- tag!( "\\ " ) => { |_| "\\ " }
388
- ) ) ) ;
389
-
390
- named ! ( empty_string_parser <& str , String >, map!( tag!( "\" \" " ) , |v| String :: from( "" ) ) ) ;
391
-
392
- named ! (
393
- string_parser<& str , String >,
394
- alt!(
395
- delimited!( tag( "\" " ) , escaped_string_parser, tag( "\" " ) ) |
396
- // Base case; empty string
397
- empty_string_parser)
398
- ) ;
399
-
400
404
to_value_parser ( string_parser) ( input)
401
405
}
402
406
403
407
pub fn try_read_pattern ( input : & str ) -> IResult < & str , Value > {
404
408
named ! ( hash_parser<& str , & str >, preceded!( consume_clojure_whitespaces_parser, tag!( "#" ) ) ) ;
405
409
406
410
let ( rest_input, _) = hash_parser ( input) ?;
407
- let ( rest_input, regex_string_val) = try_read_string ( rest_input) ?;
408
-
409
- let mut regex_string = String :: from ( "" ) ;
410
-
411
- // @TODO separate try_read_string into a parser, so we don't have to read a Value
412
- // and then unwrap it
413
- match regex_string_val {
414
- Value :: String ( reg_str) => {
415
- regex_string = reg_str;
416
- }
417
- _ => {
418
- panic ! ( "try_read_string returned something that wasn't string" ) ;
419
- }
420
- }
411
+ let ( rest_input, regex_string) = string_parser ( rest_input) ?;
421
412
422
- let regex = regex:: Regex :: new ( regex_string. as_str ( ) ) . unwrap ( ) ;
423
- Ok ( ( rest_input, Value :: Pattern ( regex) ) )
413
+ // If an error is thrown, this will be coerced into a condition
414
+ let regex = regex:: Regex :: new ( regex_string. as_str ( ) ) . to_value ( ) ;
415
+ Ok ( ( rest_input, regex) )
424
416
}
425
417
426
418
// @TODO Perhaps generalize this, or even generalize it as a reader macro
0 commit comments