Skip to content

Commit a12563d

Browse files
committed
Refactored out string_parser, so we don't have to read a whole Value::String in
our Pattern parser, and unwrap that Value::String
1 parent 361d77b commit a12563d

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

src/reader.rs

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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")
377403
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-
400404
to_value_parser(string_parser)(input)
401405
}
402406

403407
pub 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

Comments
 (0)