use super::{
filter::parse_filter,
prelude::*,
Capture,
Filter,
Pattern,
Quantifier,
};
fn parse_quantifier(input: &str) -> IResult<&str, Quantifier> {
alt((
value(Quantifier::MaybeOnce, char('?')),
value(Quantifier::Many0, char('*')),
value(Quantifier::Many1, char('+')),
))(input)
}
fn parse_name_quantifier(input: &'_ str) -> IResult<&'_ str, (&'_ str, Quantifier)> {
let name = take_while(|c: char| c.is_alphanumeric() || c == '-' || c == '_');
let quan = alt((
parse_quantifier,
success(Quantifier::Once),
));
context(
"invalid identifier name",
separated_pair(
name,
multispace0,
quan,
),
)(input)
}
fn parse_filters(input: &'_ str) -> IResult<&'_ str, Vec<Filter<'_>>> {
context(
"missing a comma separated list of filters",
list1(parse_filter, ','),
)(input)
}
pub fn parse_capture(input: &'_ str) -> IResult<&'_ str, Capture<'_>> {
let bare = map(parse_name_quantifier, |(name, quantifier)| Capture {
name,
quantifier,
patterns: vec![],
});
let full = separated_pair(
parse_name_quantifier,
wrap_space0(char(':')),
list0(parse_filters, ';'),
);
let full = map(full, |((name, quantifier), patterns)| Capture {
name,
quantifier,
patterns: patterns.into_iter().map(Pattern).collect(),
});
delimited(
char('<'),
cut(context(
"invalid capture syntax",
wrap_space0(alt((full, bare))),
)),
cut(context("missing closing delimiter: '>'", char('>'))),
)(input)
}
pub fn parse_priority_group(input: &'_ str) -> IResult<&'_ str, Vec<Capture<'_>>> {
let body = many0(wrap_space0(parse_capture));
delimited(
char('['),
body,
cut(context("missing closing delimiter: ']'", char(']'))),
)(input)
}
pub fn parse_group(input: &'_ str) -> IResult<&'_ str, Vec<Capture<'_>>> {
let body = many0(wrap_space0(parse_capture));
delimited(
char('{'),
body,
cut(context("missing closing delimiter: '}'", char('}'))),
)(input)
}