use crate::core::{ParseError, ParseResult, Parser, ParserRunner};
use crate::extension::parsers::RepeatParsers;
use crate::internal::ParsersImpl;
use crate::utils::{Bound, RangeArgument};
use std::fmt::Debug;
impl RepeatParsers for ParsersImpl {
fn repeat_sep<'a, I, A, B, R>(
parser: Self::P<'a, I, A>,
range: R,
separator: Option<Self::P<'a, I, B>>,
) -> Self::P<'a, I, Vec<A>>
where
R: RangeArgument<usize> + Debug + 'a,
A: 'a,
B: 'a, {
Parser::new(move |parse_state| {
let mut all_length = 0;
let mut items = vec![];
if let ParseResult::Success { value, length } = parser.run(parse_state) {
let mut current_parse_state = parse_state.add_offset(length);
items.push(value);
all_length += length;
loop {
match range.end() {
Bound::Included(&max_count) => {
if items.len() >= max_count {
break;
}
}
Bound::Excluded(&max_count) => {
if items.len() + 1 >= max_count {
break;
}
}
_ => (),
}
if let Some(sep) = &separator {
if let ParseResult::Success { length, .. } = sep.run(¤t_parse_state) {
current_parse_state = current_parse_state.add_offset(length);
all_length += length;
} else {
break;
}
}
if let ParseResult::Success { value, length } = parser.run(¤t_parse_state) {
current_parse_state = current_parse_state.add_offset(length);
items.push(value);
all_length += length;
} else {
break;
}
}
}
if let Bound::Included(&min_count) = range.start() {
if items.len() < min_count {
let ps = parse_state.add_offset(all_length);
let pe = ParseError::of_mismatch(
ps.input(),
ps.last_offset().unwrap_or(0),
all_length,
format!(
"expect repeat at least {} times, found {} times",
min_count,
items.len()
),
);
return ParseResult::failed_with_uncommitted(pe);
}
}
ParseResult::successful(items, all_length)
})
}
}