@@ -231,6 +231,32 @@ pub fn symbol_parser(input: &str) -> IResult<&str, Symbol> {
231231 }
232232}
233233
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+
234260// Helper function to integer_parser for same reason as
235261// identifier_tail. See comment above said function for explanation
236262
@@ -375,52 +401,18 @@ pub fn try_read_nil(input: &str) -> IResult<&str, Value> {
375401/// Example Successes:
376402/// "this is pretty straightforward" => Value::String("this is pretty straightforward")
377403pub 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-
400404 to_value_parser ( string_parser) ( input)
401405}
402406
403407pub fn try_read_pattern ( input : & str ) -> IResult < & str , Value > {
404408 named ! ( hash_parser<& str , & str >, preceded!( consume_clojure_whitespaces_parser, tag!( "#" ) ) ) ;
405409
406410 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) ?;
421412
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) )
424416}
425417
426418// @TODO Perhaps generalize this, or even generalize it as a reader macro
0 commit comments