mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 23:35:07 +00:00
refactor(parser): Remove deprecated 'char' uses
This commit is contained in:
parent
d171cdbaf1
commit
6ee949a9c6
@ -3,7 +3,7 @@ use std::str;
|
|||||||
|
|
||||||
use winnow::branch::alt;
|
use winnow::branch::alt;
|
||||||
use winnow::bytes::complete::take_till;
|
use winnow::bytes::complete::take_till;
|
||||||
use winnow::character::complete::{char, digit1};
|
use winnow::character::complete::digit1;
|
||||||
use winnow::combinator::{consumed, cut, fail, map, not, opt, peek, recognize, value};
|
use winnow::combinator::{consumed, cut, fail, map, not, opt, peek, recognize, value};
|
||||||
use winnow::error::ErrorKind;
|
use winnow::error::ErrorKind;
|
||||||
use winnow::multi::{fold_many0, many0, separated_list0, separated_list1};
|
use winnow::multi::{fold_many0, many0, separated_list0, separated_list1};
|
||||||
@ -81,10 +81,10 @@ impl<'a> Expr<'a> {
|
|||||||
let start = i;
|
let start = i;
|
||||||
|
|
||||||
preceded(
|
preceded(
|
||||||
ws(char('(')),
|
ws('('),
|
||||||
cut(terminated(
|
cut(terminated(
|
||||||
separated_list0(
|
separated_list0(
|
||||||
char(','),
|
',',
|
||||||
ws(move |i| {
|
ws(move |i| {
|
||||||
// Needed to prevent borrowing it twice between this closure and the one
|
// Needed to prevent borrowing it twice between this closure and the one
|
||||||
// calling `Self::named_arguments`.
|
// calling `Self::named_arguments`.
|
||||||
@ -114,7 +114,7 @@ impl<'a> Expr<'a> {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
tuple((opt(ws(char(','))), char(')'))),
|
tuple((opt(ws(',')), ')')),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.parse_next(i)
|
.parse_next(i)
|
||||||
@ -135,7 +135,7 @@ impl<'a> Expr<'a> {
|
|||||||
|
|
||||||
let (_, level) = level.nest(i)?;
|
let (_, level) = level.nest(i)?;
|
||||||
let (i, (argument, _, value)) =
|
let (i, (argument, _, value)) =
|
||||||
tuple((identifier, ws(char('=')), move |i| Self::parse(i, level))).parse_next(i)?;
|
tuple((identifier, ws('='), move |i| Self::parse(i, level))).parse_next(i)?;
|
||||||
if named_arguments.insert(argument) {
|
if named_arguments.insert(argument) {
|
||||||
Ok((
|
Ok((
|
||||||
i,
|
i,
|
||||||
@ -292,28 +292,28 @@ impl<'a> Expr<'a> {
|
|||||||
fn group(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> {
|
fn group(i: &'a str, level: Level) -> ParseResult<'a, WithSpan<'a, Self>> {
|
||||||
let (_, level) = level.nest(i)?;
|
let (_, level) = level.nest(i)?;
|
||||||
let start = i;
|
let start = i;
|
||||||
let (i, expr) = preceded(ws(char('(')), opt(|i| Self::parse(i, level))).parse_next(i)?;
|
let (i, expr) = preceded(ws('('), opt(|i| Self::parse(i, level))).parse_next(i)?;
|
||||||
let Some(expr) = expr else {
|
let Some(expr) = expr else {
|
||||||
let (i, _) = char(')').parse_next(i)?;
|
let (i, _) = ')'.parse_next(i)?;
|
||||||
return Ok((i, WithSpan::new(Self::Tuple(vec![]), start)));
|
return Ok((i, WithSpan::new(Self::Tuple(vec![]), start)));
|
||||||
};
|
};
|
||||||
|
|
||||||
let (i, comma) = ws(opt(peek(char(',')))).parse_next(i)?;
|
let (i, comma) = ws(opt(peek(','))).parse_next(i)?;
|
||||||
if comma.is_none() {
|
if comma.is_none() {
|
||||||
let (i, _) = char(')').parse_next(i)?;
|
let (i, _) = ')'.parse_next(i)?;
|
||||||
return Ok((i, WithSpan::new(Self::Group(Box::new(expr)), start)));
|
return Ok((i, WithSpan::new(Self::Group(Box::new(expr)), start)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut exprs = vec![expr];
|
let mut exprs = vec![expr];
|
||||||
let (i, ()) = fold_many0(
|
let (i, ()) = fold_many0(
|
||||||
preceded(char(','), ws(|i| Self::parse(i, level))),
|
preceded(',', ws(|i| Self::parse(i, level))),
|
||||||
|| (),
|
|| (),
|
||||||
|(), expr| {
|
|(), expr| {
|
||||||
exprs.push(expr);
|
exprs.push(expr);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
let (i, _) = pair(ws(opt(char(','))), char(')')).parse_next(i)?;
|
let (i, _) = pair(ws(opt(',')), ')').parse_next(i)?;
|
||||||
Ok((i, WithSpan::new(Self::Tuple(exprs), start)))
|
Ok((i, WithSpan::new(Self::Tuple(exprs), start)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,13 +321,13 @@ impl<'a> Expr<'a> {
|
|||||||
let start = i;
|
let start = i;
|
||||||
let (i, level) = level.nest(i)?;
|
let (i, level) = level.nest(i)?;
|
||||||
let (i, array) = preceded(
|
let (i, array) = preceded(
|
||||||
ws(char('[')),
|
ws('['),
|
||||||
cut(terminated(
|
cut(terminated(
|
||||||
opt(terminated(
|
opt(terminated(
|
||||||
separated_list1(char(','), ws(move |i| Self::parse(i, level))),
|
separated_list1(',', ws(move |i| Self::parse(i, level))),
|
||||||
ws(opt(char(','))),
|
ws(opt(',')),
|
||||||
)),
|
)),
|
||||||
char(']'),
|
']',
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
@ -396,7 +396,7 @@ impl<'a> Expr<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn token_xor(i: &str) -> ParseResult<'_> {
|
fn token_xor(i: &str) -> ParseResult<'_> {
|
||||||
let (i, good) = alt((value(true, keyword("xor")), value(false, char('^')))).parse_next(i)?;
|
let (i, good) = alt((value(true, keyword("xor")), value(false, '^'))).parse_next(i)?;
|
||||||
if good {
|
if good {
|
||||||
Ok((i, "^"))
|
Ok((i, "^"))
|
||||||
} else {
|
} else {
|
||||||
@ -410,7 +410,7 @@ fn token_xor(i: &str) -> ParseResult<'_> {
|
|||||||
fn token_bitand(i: &str) -> ParseResult<'_> {
|
fn token_bitand(i: &str) -> ParseResult<'_> {
|
||||||
let (i, good) = alt((
|
let (i, good) = alt((
|
||||||
value(true, keyword("bitand")),
|
value(true, keyword("bitand")),
|
||||||
value(false, pair(char('&'), not(char('&')))),
|
value(false, pair('&', not('&'))),
|
||||||
))
|
))
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
if good {
|
if good {
|
||||||
@ -519,10 +519,10 @@ impl<'a> Suffix<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
preceded(
|
preceded(
|
||||||
pair(ws(char('!')), char('(')),
|
pair(ws('!'), '('),
|
||||||
cut(terminated(
|
cut(terminated(
|
||||||
map(recognize(nested_parenthesis), Self::MacroCall),
|
map(recognize(nested_parenthesis), Self::MacroCall),
|
||||||
char(')'),
|
')',
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.parse_next(i)
|
.parse_next(i)
|
||||||
@ -530,10 +530,7 @@ impl<'a> Suffix<'a> {
|
|||||||
|
|
||||||
fn attr(i: &'a str) -> ParseResult<'a, Self> {
|
fn attr(i: &'a str) -> ParseResult<'a, Self> {
|
||||||
map(
|
map(
|
||||||
preceded(
|
preceded(ws(pair('.', not('.'))), cut(alt((digit1, identifier)))),
|
||||||
ws(pair(char('.'), not(char('.')))),
|
|
||||||
cut(alt((digit1, identifier))),
|
|
||||||
),
|
|
||||||
Self::Attr,
|
Self::Attr,
|
||||||
)
|
)
|
||||||
.parse_next(i)
|
.parse_next(i)
|
||||||
@ -543,8 +540,8 @@ impl<'a> Suffix<'a> {
|
|||||||
let (_, level) = level.nest(i)?;
|
let (_, level) = level.nest(i)?;
|
||||||
map(
|
map(
|
||||||
preceded(
|
preceded(
|
||||||
ws(char('[')),
|
ws('['),
|
||||||
cut(terminated(ws(move |i| Expr::parse(i, level)), char(']'))),
|
cut(terminated(ws(move |i| Expr::parse(i, level)), ']')),
|
||||||
),
|
),
|
||||||
Self::Index,
|
Self::Index,
|
||||||
)
|
)
|
||||||
@ -557,6 +554,6 @@ impl<'a> Suffix<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn r#try(i: &'a str) -> ParseResult<'a, Self> {
|
fn r#try(i: &'a str) -> ParseResult<'a, Self> {
|
||||||
map(preceded(take_till(not_ws), char('?')), |_| Self::Try).parse_next(i)
|
map(preceded(take_till(not_ws), '?'), |_| Self::Try).parse_next(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use std::{fmt, str};
|
|||||||
use winnow::Parser;
|
use winnow::Parser;
|
||||||
use winnow::branch::alt;
|
use winnow::branch::alt;
|
||||||
use winnow::bytes::complete::{escaped, is_not, tag, take_till, take_while_m_n, take_while1};
|
use winnow::bytes::complete::{escaped, is_not, tag, take_till, take_while_m_n, take_while1};
|
||||||
use winnow::character::complete::{anychar, char, one_of, satisfy};
|
use winnow::character::complete::{anychar, one_of, satisfy};
|
||||||
use winnow::combinator::{consumed, cut, fail, map, not, opt, recognize, value};
|
use winnow::combinator::{consumed, cut, fail, map, not, opt, recognize, value};
|
||||||
use winnow::error::{ErrorKind, FromExternalError};
|
use winnow::error::{ErrorKind, FromExternalError};
|
||||||
use winnow::multi::{many0_count, many1};
|
use winnow::multi::{many0_count, many1};
|
||||||
@ -370,14 +370,10 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L587-L620>.
|
// Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L587-L620>.
|
||||||
let int_with_base = pair(opt(char('-')), |i| {
|
let int_with_base = pair(opt('-'), |i| {
|
||||||
let (i, (kind, base)) = consumed(preceded(
|
let (i, (kind, base)) = consumed(preceded(
|
||||||
char('0'),
|
'0',
|
||||||
alt((
|
alt((value(2, 'b'), value(8, 'o'), value(16, 'x'))),
|
||||||
value(2, char('b')),
|
|
||||||
value(8, char('o')),
|
|
||||||
value(16, char('x')),
|
|
||||||
)),
|
|
||||||
))
|
))
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
match opt(separated_digits(base, false)).parse_next(i)? {
|
match opt(separated_digits(base, false)).parse_next(i)? {
|
||||||
@ -392,7 +388,7 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
|
|||||||
// Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L626-L653>:
|
// Equivalent to <https://github.com/rust-lang/rust/blob/e3f909b2bbd0b10db6f164d466db237c582d3045/compiler/rustc_lexer/src/lib.rs#L626-L653>:
|
||||||
// no `_` directly after the decimal point `.`, or between `e` and `+/-`.
|
// no `_` directly after the decimal point `.`, or between `e` and `+/-`.
|
||||||
let float = |i: &'a str| -> ParseResult<'a, ()> {
|
let float = |i: &'a str| -> ParseResult<'a, ()> {
|
||||||
let (i, has_dot) = opt(pair(char('.'), separated_digits(10, true))).parse_next(i)?;
|
let (i, has_dot) = opt(pair('.', separated_digits(10, true))).parse_next(i)?;
|
||||||
let (i, has_exp) = opt(|i| {
|
let (i, has_exp) = opt(|i| {
|
||||||
let (i, (kind, op)) = pair(one_of("eE"), opt(one_of("+-"))).parse_next(i)?;
|
let (i, (kind, op)) = pair(one_of("eE"), opt(one_of("+-"))).parse_next(i)?;
|
||||||
match opt(separated_digits(10, op.is_none())).parse_next(i)? {
|
match opt(separated_digits(10, op.is_none())).parse_next(i)? {
|
||||||
@ -416,7 +412,7 @@ fn num_lit<'a>(start: &'a str) -> ParseResult<'a, Num<'a>> {
|
|||||||
(i, Num::Int(num, suffix))
|
(i, Num::Int(num, suffix))
|
||||||
} else {
|
} else {
|
||||||
let (i, (num, float)) = consumed(preceded(
|
let (i, (num, float)) = consumed(preceded(
|
||||||
pair(opt(char('-')), separated_digits(10, true)),
|
pair(opt('-'), separated_digits(10, true)),
|
||||||
opt(float),
|
opt(float),
|
||||||
))
|
))
|
||||||
.parse_next(start)?;
|
.parse_next(start)?;
|
||||||
@ -444,7 +440,7 @@ fn separated_digits(radix: u32, start: bool) -> impl Fn(&str) -> ParseResult<'_>
|
|||||||
recognize(tuple((
|
recognize(tuple((
|
||||||
|i| match start {
|
|i| match start {
|
||||||
true => Ok((i, 0)),
|
true => Ok((i, 0)),
|
||||||
false => many0_count(char('_')).parse_next(i),
|
false => many0_count('_').parse_next(i),
|
||||||
},
|
},
|
||||||
satisfy(|ch| ch.is_digit(radix)),
|
satisfy(|ch| ch.is_digit(radix)),
|
||||||
many0_count(satisfy(|ch| ch == '_' || ch.is_digit(radix))),
|
many0_count(satisfy(|ch| ch == '_' || ch.is_digit(radix))),
|
||||||
@ -484,18 +480,13 @@ pub struct StrLit<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn str_lit_without_prefix(i: &str) -> ParseResult<'_> {
|
fn str_lit_without_prefix(i: &str) -> ParseResult<'_> {
|
||||||
let (i, s) = delimited(
|
let (i, s) = delimited('"', opt(escaped(is_not("\\\""), '\\', anychar)), '"').parse_next(i)?;
|
||||||
char('"'),
|
|
||||||
opt(escaped(is_not("\\\""), '\\', anychar)),
|
|
||||||
char('"'),
|
|
||||||
)
|
|
||||||
.parse_next(i)?;
|
|
||||||
Ok((i, s.unwrap_or_default()))
|
Ok((i, s.unwrap_or_default()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn str_lit(i: &str) -> Result<(&str, StrLit<'_>), ParseErr<'_>> {
|
fn str_lit(i: &str) -> Result<(&str, StrLit<'_>), ParseErr<'_>> {
|
||||||
let (i, (prefix, content)) =
|
let (i, (prefix, content)) =
|
||||||
tuple((opt(alt((char('b'), char('c')))), str_lit_without_prefix)).parse_next(i)?;
|
tuple((opt(alt(('b', 'c'))), str_lit_without_prefix)).parse_next(i)?;
|
||||||
let prefix = match prefix {
|
let prefix = match prefix {
|
||||||
Some('b') => Some(StrPrefix::Binary),
|
Some('b') => Some(StrPrefix::Binary),
|
||||||
Some('c') => Some(StrPrefix::CLike),
|
Some('c') => Some(StrPrefix::CLike),
|
||||||
@ -520,12 +511,8 @@ pub struct CharLit<'a> {
|
|||||||
fn char_lit(i: &str) -> Result<(&str, CharLit<'_>), ParseErr<'_>> {
|
fn char_lit(i: &str) -> Result<(&str, CharLit<'_>), ParseErr<'_>> {
|
||||||
let start = i;
|
let start = i;
|
||||||
let (i, (b_prefix, s)) = tuple((
|
let (i, (b_prefix, s)) = tuple((
|
||||||
opt(char('b')),
|
opt('b'),
|
||||||
delimited(
|
delimited('\'', opt(escaped(is_not("\\\'"), '\\', anychar)), '\''),
|
||||||
char('\''),
|
|
||||||
opt(escaped(is_not("\\\'"), '\\', anychar)),
|
|
||||||
char('\''),
|
|
||||||
),
|
|
||||||
))
|
))
|
||||||
.parse_next(i)?;
|
.parse_next(i)?;
|
||||||
|
|
||||||
@ -597,28 +584,25 @@ impl<'a> Char<'a> {
|
|||||||
}
|
}
|
||||||
map(
|
map(
|
||||||
tuple((
|
tuple((
|
||||||
char('\\'),
|
'\\',
|
||||||
alt((
|
alt((
|
||||||
map(char('n'), |_| Self::Escaped),
|
map('n', |_| Self::Escaped),
|
||||||
map(char('r'), |_| Self::Escaped),
|
map('r', |_| Self::Escaped),
|
||||||
map(char('t'), |_| Self::Escaped),
|
map('t', |_| Self::Escaped),
|
||||||
map(char('\\'), |_| Self::Escaped),
|
map('\\', |_| Self::Escaped),
|
||||||
map(char('0'), |_| Self::Escaped),
|
map('0', |_| Self::Escaped),
|
||||||
map(char('\''), |_| Self::Escaped),
|
map('\'', |_| Self::Escaped),
|
||||||
// Not useful but supported by rust.
|
// Not useful but supported by rust.
|
||||||
map(char('"'), |_| Self::Escaped),
|
map('"', |_| Self::Escaped),
|
||||||
map(
|
map(
|
||||||
tuple((
|
tuple(('x', take_while_m_n(2, 2, |c: char| c.is_ascii_hexdigit()))),
|
||||||
char('x'),
|
|
||||||
take_while_m_n(2, 2, |c: char| c.is_ascii_hexdigit()),
|
|
||||||
)),
|
|
||||||
|(_, s)| Self::AsciiEscape(s),
|
|(_, s)| Self::AsciiEscape(s),
|
||||||
),
|
),
|
||||||
map(
|
map(
|
||||||
tuple((
|
tuple((
|
||||||
"u{",
|
"u{",
|
||||||
take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit()),
|
take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit()),
|
||||||
char('}'),
|
'}',
|
||||||
)),
|
)),
|
||||||
|(_, s, _)| Self::UnicodeEscape(s),
|
|(_, s, _)| Self::UnicodeEscape(s),
|
||||||
),
|
),
|
||||||
@ -900,7 +884,7 @@ fn filter<'a>(
|
|||||||
) -> ParseResult<'a, (&'a str, Option<Vec<WithSpan<'a, Expr<'a>>>>)> {
|
) -> ParseResult<'a, (&'a str, Option<Vec<WithSpan<'a, Expr<'a>>>>)> {
|
||||||
let (j, _) = take_till(not_ws).parse_next(i)?;
|
let (j, _) = take_till(not_ws).parse_next(i)?;
|
||||||
let had_spaces = i.len() != j.len();
|
let had_spaces = i.len() != j.len();
|
||||||
let (j, _) = pair(char('|'), not(char('|'))).parse_next(j)?;
|
let (j, _) = pair('|', not('|')).parse_next(j)?;
|
||||||
|
|
||||||
if !had_spaces {
|
if !had_spaces {
|
||||||
*level = level.nest(i)?.1;
|
*level = level.nest(i)?.1;
|
||||||
|
@ -3,7 +3,7 @@ use std::str;
|
|||||||
use winnow::Parser;
|
use winnow::Parser;
|
||||||
use winnow::branch::alt;
|
use winnow::branch::alt;
|
||||||
use winnow::bytes::complete::{tag, take_till};
|
use winnow::bytes::complete::{tag, take_till};
|
||||||
use winnow::character::complete::{anychar, char};
|
use winnow::character::complete::anychar;
|
||||||
use winnow::combinator::{
|
use winnow::combinator::{
|
||||||
complete, consumed, cut, eof, fail, map, map_opt, not, opt, peek, recognize, value,
|
complete, consumed, cut, eof, fail, map, map_opt, not, opt, peek, recognize, value,
|
||||||
};
|
};
|
||||||
@ -328,7 +328,7 @@ impl<'a> When<'a> {
|
|||||||
cut_node(
|
cut_node(
|
||||||
Some("match-when"),
|
Some("match-when"),
|
||||||
tuple((
|
tuple((
|
||||||
separated_list1(char('|'), ws(|i| Target::parse(i, s))),
|
separated_list1('|', ws(|i| Target::parse(i, s))),
|
||||||
opt(Whitespace::parse),
|
opt(Whitespace::parse),
|
||||||
|i| s.tag_block_end(i),
|
|i| s.tag_block_end(i),
|
||||||
cut_node(Some("match-when"), |i| Node::many(i, s)),
|
cut_node(Some("match-when"), |i| Node::many(i, s)),
|
||||||
@ -414,7 +414,7 @@ impl<'a> CondTest<'a> {
|
|||||||
opt(delimited(
|
opt(delimited(
|
||||||
ws(alt((keyword("let"), keyword("set")))),
|
ws(alt((keyword("let"), keyword("set")))),
|
||||||
ws(|i| Target::parse(i, s)),
|
ws(|i| Target::parse(i, s)),
|
||||||
ws(char('=')),
|
ws('='),
|
||||||
)),
|
)),
|
||||||
ws(|i| Expr::parse(i, s.level.get())),
|
ws(|i| Expr::parse(i, s.level.get())),
|
||||||
)
|
)
|
||||||
@ -590,9 +590,9 @@ impl<'a> Macro<'a> {
|
|||||||
fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, WithSpan<'a, Self>> {
|
fn parse(i: &'a str, s: &State<'_>) -> ParseResult<'a, WithSpan<'a, Self>> {
|
||||||
fn parameters(i: &str) -> ParseResult<'_, Vec<&str>> {
|
fn parameters(i: &str) -> ParseResult<'_, Vec<&str>> {
|
||||||
delimited(
|
delimited(
|
||||||
ws(char('(')),
|
ws('('),
|
||||||
separated_list0(char(','), ws(identifier)),
|
separated_list0(',', ws(identifier)),
|
||||||
tuple((opt(ws(char(','))), char(')'))),
|
tuple((opt(ws(',')), ')')),
|
||||||
)
|
)
|
||||||
.parse_next(i)
|
.parse_next(i)
|
||||||
}
|
}
|
||||||
@ -1084,10 +1084,7 @@ impl<'a> Let<'a> {
|
|||||||
Some("let"),
|
Some("let"),
|
||||||
tuple((
|
tuple((
|
||||||
ws(|i| Target::parse(i, s)),
|
ws(|i| Target::parse(i, s)),
|
||||||
opt(preceded(
|
opt(preceded(ws('='), ws(|i| Expr::parse(i, s.level.get())))),
|
||||||
ws(char('=')),
|
|
||||||
ws(|i| Expr::parse(i, s.level.get())),
|
|
||||||
)),
|
|
||||||
opt(Whitespace::parse),
|
opt(Whitespace::parse),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
|
@ -42,9 +42,9 @@ impl<'a> Target<'a> {
|
|||||||
|
|
||||||
/// Parses a single target without an `or`, unless it is wrapped in parentheses.
|
/// Parses a single target without an `or`, unless it is wrapped in parentheses.
|
||||||
fn parse_one(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {
|
fn parse_one(i: &'a str, s: &State<'_>) -> ParseResult<'a, Self> {
|
||||||
let mut opt_opening_paren = map(opt(ws(char('('))), |o| o.is_some());
|
let mut opt_opening_paren = map(opt(ws('(')), |o| o.is_some());
|
||||||
let mut opt_opening_brace = map(opt(ws(char('{'))), |o| o.is_some());
|
let mut opt_opening_brace = map(opt(ws('{')), |o| o.is_some());
|
||||||
let mut opt_opening_bracket = map(opt(ws(char('['))), |o| o.is_some());
|
let mut opt_opening_bracket = map(opt(ws('[')), |o| o.is_some());
|
||||||
|
|
||||||
let (i, lit) = opt(Self::lit).parse_next(i)?;
|
let (i, lit) = opt(Self::lit).parse_next(i)?;
|
||||||
if let Some(lit) = lit {
|
if let Some(lit) = lit {
|
||||||
@ -154,10 +154,8 @@ impl<'a> Target<'a> {
|
|||||||
return Ok((i, rest));
|
return Ok((i, rest));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (i, (src, target)) = pair(
|
let (i, (src, target)) =
|
||||||
identifier,
|
pair(identifier, opt(preceded(ws(':'), |i| Self::parse(i, s))))(init_i)?;
|
||||||
opt(preceded(ws(char(':')), |i| Self::parse(i, s))),
|
|
||||||
)(init_i)?;
|
|
||||||
|
|
||||||
if src == "_" {
|
if src == "_" {
|
||||||
return Err(winnow::Err::Cut(ErrorContext::new(
|
return Err(winnow::Err::Cut(ErrorContext::new(
|
||||||
@ -174,8 +172,7 @@ impl<'a> Target<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rest(start: &'a str) -> ParseResult<'a, Self> {
|
fn rest(start: &'a str) -> ParseResult<'a, Self> {
|
||||||
let (i, (ident, _)) =
|
let (i, (ident, _)) = tuple((opt(tuple((identifier, ws('@')))), "..")).parse_next(start)?;
|
||||||
tuple((opt(tuple((identifier, ws(char('@'))))), "..")).parse_next(start)?;
|
|
||||||
Ok((
|
Ok((
|
||||||
i,
|
i,
|
||||||
Self::Rest(WithSpan::new(ident.map(|(ident, _)| ident), start)),
|
Self::Rest(WithSpan::new(ident.map(|(ident, _)| ident), start)),
|
||||||
@ -202,7 +199,7 @@ fn collect_targets<'a, T>(
|
|||||||
delim: char,
|
delim: char,
|
||||||
mut one: impl FnMut(&'a str, &State<'_>) -> ParseResult<'a, T>,
|
mut one: impl FnMut(&'a str, &State<'_>) -> ParseResult<'a, T>,
|
||||||
) -> ParseResult<'a, (bool, Vec<T>)> {
|
) -> ParseResult<'a, (bool, Vec<T>)> {
|
||||||
let opt_comma = |i| map(ws(opt(char(','))), |o| o.is_some()).parse_next(i);
|
let opt_comma = |i| map(ws(opt(',')), |o| o.is_some()).parse_next(i);
|
||||||
let mut opt_end = |i| map(ws(opt(char(delim))), |o| o.is_some()).parse_next(i);
|
let mut opt_end = |i| map(ws(opt(char(delim))), |o| o.is_some()).parse_next(i);
|
||||||
|
|
||||||
let (i, has_end) = opt_end.parse_next(i)?;
|
let (i, has_end) = opt_end.parse_next(i)?;
|
||||||
@ -211,7 +208,7 @@ fn collect_targets<'a, T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (i, targets) =
|
let (i, targets) =
|
||||||
opt(separated_list1(ws(char(',')), |i| one(i, s)).map(|v: Vec<_>| v)).parse_next(i)?;
|
opt(separated_list1(ws(','), |i| one(i, s)).map(|v: Vec<_>| v)).parse_next(i)?;
|
||||||
let Some(targets) = targets else {
|
let Some(targets) = targets else {
|
||||||
return Err(winnow::Err::Cut(ErrorContext::new(
|
return Err(winnow::Err::Cut(ErrorContext::new(
|
||||||
"expected comma separated list of members",
|
"expected comma separated list of members",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user