use mipl::prelude::*;
mod common;
use common::*;
fn assert_parsers_same_till(
mut a: Parser,
mut b: Parser,
n: usize
) {
let mut i: usize = 0;
while i < n {
assert_eq!(a.next(), b.next());
i += 1;
}
}
fn not_assert_parsers_same_till(
mut a: Parser,
mut b: Parser,
n: usize
) {
let mut i: usize = 0;
let mut not: bool = false;
while i < n {
if a.next() != b.next() {
not = true;
break;
}
i += i;
}
assert!(not)
}
#[test]
fn test_collect_until_exact_match_subparser() {
let mut parser = setup_space_seps_parser(
"a b c d e f g h"
);
let mut known_subparser = setup_space_seps_parser(
"a b c d"
);
let mut subparser = CollectUntil::<ExactMatch>::subparse(
"e".to_string(),
&mut parser
);
let mut i: usize = 0;
while i < 4 {
assert_eq!(known_subparser.next(), subparser.next());
i += 1;
}
}
#[test]
fn test_collect_until_is_newline() {
let mut parser = setup_space_seps_parser(
"a b\n c d e f g h"
);
let mut known_subparser = setup_space_seps_parser(
"a b"
);
let mut subparser = CollectUntil::<IsNewline>::subparse(
(),
&mut parser
);
let mut i: usize = 0;
while i < 2 {
assert_eq!(known_subparser.next(), subparser.next());
i += 1;
}
}
#[test]
fn test_collect_while_exact_match() {
let mut parser = setup_space_seps_parser(
"a a a a e f g h"
);
let mut known_subparser = setup_space_seps_parser(
"a a a a"
);
let mut subparser = CollectWhile::<ExactMatch>::subparse(
"a".to_string(),
&mut parser
);
let mut i: usize = 0;
while i < 4 {
assert_eq!(known_subparser.next(), subparser.next());
i += 1;
}
}
#[test]
fn test_collect_if_sequence() {
let mut parser = setup_space_seps_parser(
"a b c d e f g h i j"
);
let known_subparser = setup_space_seps_parser(
"a b c d"
);
let values: Vec<String> = vec!["a", "b", "c", "d", "e"]
.into_iter()
.map(String::from)
.collect();
let subparser = CollectIfSeq::<ExactMatch>::subparse(
values,
&mut parser
);
assert_parsers_same_till(
known_subparser,
subparser,
4
);
}
#[test]
fn test_collect_if_exact_sequence() {
let mut parser = setup_space_seps_parser(
"a b c d e f g h i j"
);
let known_subparser = setup_space_seps_parser(
"a b"
);
let values: Vec<String> = vec!["a", "b", "c", "d"]
.into_iter()
.map(String::from)
.collect();
let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
values,
&mut parser
);
assert_parsers_same_till(
known_subparser,
subparser,
2
);
}
#[test]
fn test_fail_collect_if_exact_sequence() {
let mut parser = setup_space_seps_parser(
"a b c d e f g h i j"
);
let known_subparser = setup_space_seps_parser(
"a b c d"
);
let values: Vec<String> = vec!["a", "b", "c", "d", "f"]
.into_iter()
.map(String::from)
.collect();
let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
values,
&mut parser
);
not_assert_parsers_same_till(
known_subparser,
subparser,
4
);
}
#[test]
fn test_fail_collect_if_exact_keeps_parent_parser_intact() {
let mut parser = setup_space_seps_parser(
"a b c d"
);
let initial_parser = parser.clone();
let values: Vec<String> = vec!["a", "b", "c", "e"]
.into_iter()
.map(String::from)
.collect();
let _subparser = CollectIfExactSeq::<ExactMatch>::subparse(
values,
&mut parser
);
println!("{:#?}", parser);
assert_parsers_same_till(parser, initial_parser, 4);
}
pub fn tokenize(src: String) -> Parser {
let del_param = DelimitersParam{
discard: DiscardDelimiters::new(
vec![
' ',
'\n',
'\t'
]
),
keep: KeepDelimiters::new(
vec![
'(',
')',
'~',
'&',
'|',
'=',
'>',
'<',
'*',
'#'
]
)
};
Parser::from(src, del_param)
}
fn test_until_doesnt_eat_ending_states_subparser(parser: &mut Parser) -> Parser {
let states: Vec<String> = vec!["*", "#"]
.into_iter()
.map(String::from)
.collect();
let _expr_parser = CollectUntil::<OrExactMatch>::subparse(states.clone(), parser);
let states_parser = CollectWhile::<OrExactMatch>::subparse(states, parser);
states_parser
}
#[test]
fn test_until_doesnt_eat_ending() {
let src = "(l | r) & (~l | ~r) **# 16".to_string();
let mut flat_parser = tokenize(src);
let known_parser_a = tokenize("**#".to_string());
let states_parser = test_until_doesnt_eat_ending_states_subparser(&mut flat_parser);
assert_parsers_same_till(known_parser_a, states_parser, 3);
}