Skip to content

Commit

Permalink
internal: string parser with chumsky
Browse files Browse the repository at this point in the history
  • Loading branch information
jcornaz committed Mar 3, 2024
1 parent 6af51d9 commit b04a715
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,44 @@ trait ChumskyParser<O>: chumsky::Parser<char, O, Error = ChumskyError> {}

#[cfg(test)]
impl<O, P: chumsky::Parser<char, O, Error = ChumskyError>> ChumskyParser<O> for P {}

#[cfg(test)]
mod chumksy {
use chumsky::prelude::*;

use crate::ChumskyParser;

fn string() -> impl ChumskyParser<String> {
choice((just("\\\"").to('"'), just("\\\\").to('\\'), just('"').not()))
.repeated()
.delimited_by(just('"'), just('"'))
.collect()
.labelled("string")
}

#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;

#[rstest]
#[case::empty("\"\"", "")]
#[case::normal("\"hello\"", "hello")]
#[case::escaped_quote("\"hello \\\"world\\\"\"", "hello \"world\"")]
#[case::escaped_backslash("\"hello\\\\world\"", "hello\\world")]
fn should_parse_valid_string(#[case] input: &str, #[case] expected: &str) {
let string: String = string().then_ignore(end()).parse(input).unwrap();
assert_eq!(string, expected);
}

#[rstest]
#[case::nothing("")]
#[case::not_quoted("hello")]
#[case::not_closed("\"hello")]
#[case::not_closed_escaped("\"hello\\\"")]
fn should_not_parse_invalid_string(#[case] input: &str) {
let result: Result<String, _> = string().then_ignore(end()).parse(input);
assert!(result.is_err(), "{result:?}");
}
}
}

0 comments on commit b04a715

Please sign in to comment.