我的测试parse_line_repeat
在最后一行崩溃(这在这一点上是无效的),而不是像测试本身所示将其作为余数返回.
我试着用tuple
代替pair
,many0
代替many1
,第一个用this blogpost on nom解,第二个再读documentation on choosing a combinator.
我想要做的可能被描述为错误恢复,但这article不是这样说的,因此我不知道为什么要搜索.
这是lib.rs
美元
use nom::{
branch::alt,
bytes::complete::tag,
character::complete::space0,
multi::{many1, many_till},
sequence::pair,
IResult,
};
fn parse_token(input: &str) -> IResult<&str, bool> {
let (remaining, token) = alt((tag("0"), tag("1")))(input)?;
if token == "1" {
return Ok((remaining, true));
} else {
return Ok((remaining, false));
}
}
#[allow(dead_code)]
fn parse_line(input: &str) -> IResult<&str, Vec<bool>> {
let (remaining, (tokens_raw, _)) = pair(
many1(many_till(space0, parse_token)),
many_till(space0, tag("\n")),
)(input)?;
let mut tokens = Vec::new();
for (_, token) in tokens_raw {
let token: bool = token;
tokens.push(token);
}
Ok((remaining, tokens))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_token_test() {
assert_eq!(parse_token("0"), Ok(("", false)));
assert_eq!(parse_token("1"), Ok(("", true)));
}
#[test]
fn parse_line_test() {
assert_eq!(parse_line("1 \n"), Ok(("", vec![true])));
assert_eq!(parse_line("0 \n"), Ok(("", vec![false])));
assert_eq!(
parse_line("1 1 1 1\n"),
Ok(("", vec![true, true, true, true]))
);
}
#[test]
fn parse_line_repeat() {
let rtn = parse_line("1 \n 1\n");
assert_eq!(rtn, Ok((" 1\n", vec![true])));
let rtn = parse_line(rtn.unwrap().0);
assert_eq!(rtn, Ok(("", vec![true])));
let rtn = parse_line("1\n 1\n\n");
assert_eq!(rtn, Ok((" 1\n\n", vec![true])));
let rtn = parse_line(rtn.unwrap().0);
assert_eq!(rtn, Ok(("\n", vec![true])));
let rtn = parse_line(rtn.unwrap().0);
assert_eq!(rtn, Ok(("\n", vec![])));
}
}
这是Cargo.toml
美元
[package]
name = "minimal"
version = "0.1.0"
edition = "2021"
[lib]
name = "minimal"
path = "src/lib.rs"
[dependencies]
nom = "7.1.3"
错误:
$ cargo test
Finished test [unoptimized + debuginfo] target(s) in 0.94s
Running unittests minimal/main.rs
running 3 tests
test tests::parse_line_test ... ok
test tests::parse_token_test ... ok
test tests::parse_line_repeat ... FAILED
failures:
---- tests::parse_line_repeat stdout ----
thread 'tests::parse_line_repeat' panicked at 'assertion failed: `(left == right)`
left: `Err(Error(Error { input: "\n", code: ManyTill }))`,
right: `Ok(("\n", []))`', minimal/main.rs:67:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::parse_line_repeat
test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass `--lib`