use crate::{
Check,
container::SeparatorsContainer,
emitter::{BatchEmitter, RepeatedEmitter, SeparatedByEmitter},
error::{
syntax::{FullContainer, MissingSyntaxOf, TooFew, TooMany},
token::{
MissingLeadingOf, MissingSeparatorOf, MissingTrailingOf, UnexpectedLeadingOf,
UnexpectedRepeatedOf, UnexpectedTrailingOf,
},
},
lexer::{Checkpoint, Span},
};
use super::*;
use core::mem;
impl<
'inp,
L,
F,
SepClassifier,
Condition,
O,
Container,
Ctx,
Trailing,
Leading,
Max,
Min,
Lang: ?Sized,
W,
> ParseInput<'inp, L, Container, Ctx, Lang>
for Collect<
SeparatedBy<
F,
SepClassifier,
Condition,
O,
W,
L,
Ctx,
SeparatedByOptions<Trailing, Leading, Max, Min>,
Lang,
>,
Container,
Ctx,
Lang,
>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
Container: Default + SeparatorsContainer<Spanned<L::Token, L::Span>, O>,
W: Window,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<Container, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
self
.as_mut()
.map_parser(|p| p.as_mut())
.parse_input(inp)
.map(|_| mem::take(&mut self.container))
}
}
impl<
'inp,
L,
F,
SepClassifier,
Condition,
O,
Container,
Ctx,
Trailing,
Leading,
Max,
Min,
Lang: ?Sized,
W,
> ParseInput<'inp, L, Spanned<Container, L::Span>, Ctx, Lang>
for With<
Collect<
SeparatedBy<
F,
SepClassifier,
Condition,
O,
W,
L,
Ctx,
SeparatedByOptions<Trailing, Leading, Max, Min>,
Lang,
>,
Container,
Ctx,
Lang,
>,
PhantomSpan,
>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
Container: Default + SeparatorsContainer<Spanned<L::Token, L::Span>, O>,
W: Window,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<Spanned<Container, L::Span>, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
self
.primary_mut()
.as_mut()
.map_parser(|p| p.as_mut())
.parse_input(inp)
.map(|span| Spanned::new(span, mem::take(&mut self.primary.container)))
}
}
impl<
'inp,
'c,
L,
F,
SepClassifier,
Condition,
O,
Container,
Ctx,
Trailing,
Leading,
Max,
Min,
Lang: ?Sized,
W,
> ParseInput<'inp, L, L::Span, Ctx, Lang>
for Collect<
&'c mut SeparatedBy<
&'c mut F,
&'c mut SepClassifier,
Condition,
O,
W,
L,
Ctx,
&'c mut SeparatedByOptions<Trailing, Leading, Max, Min>,
Lang,
>,
&'c mut Container,
Ctx,
Lang,
>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
Container: SeparatorsContainer<Spanned<L::Token, L::Span>, O>,
W: Window,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
let Self {
parser:
SeparatedBy {
f,
sep,
condition,
config,
..
},
container,
..
} = self;
let mut parser = SeparatedBy {
f: &mut **f,
sep: &mut **sep,
condition: &mut *condition,
config: &mut **config,
_m: PhantomData,
_decision_window: PhantomData,
_ctx: PhantomData,
_l: PhantomData,
_lang: PhantomData,
}
.collect_with(&mut *container);
parser.parse_input(input)
}
}
impl<
'inp,
'c,
L,
F,
SepClassifier,
Condition,
O,
Container,
Ctx,
Trailing,
Leading,
Max,
Min,
Lang: ?Sized,
W,
> ParseInput<'inp, L, L::Span, Ctx, Lang>
for Collect<
SeparatedBy<
&'c mut F,
&'c mut SepClassifier,
&'c mut Condition,
O,
W,
L,
Ctx,
&'c mut SeparatedByOptions<Trailing, Leading, Max, Min>,
Lang,
>,
&'c mut Container,
Ctx,
Lang,
>
where
L: Lexer<'inp>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Ctx: ParseContext<'inp, L, Lang>,
Container: SeparatorsContainer<Spanned<L::Token, L::Span>, O>,
W: Window,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
fn parse_input(
&mut self,
inp: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
let Self {
parser, container, ..
} = self;
let mut state: State<L::Token, L::Span> = State::Start;
let ckp = inp.save();
let leading_spec = parser.config.leading();
let mut num_elems = 0;
loop {
let (peeked, emitter) = inp.sync_until_token_then_peek_with_emitter::<W>()?;
let peek_span = match peeked.front() {
None => {
drop(peeked);
return parser.handle_end(state, inp, &ckp, num_elems, container);
}
Some(tok) => {
let tok = tok
.as_maybe_ref()
.map(
|t| t.token().map(|t| *t, |t| t.unwrap_token_ref()),
|t| t.token().map_data(|t| t.unwrap_token_ref()),
)
.into_inner();
let peek_span = tok.span();
match tok.data() {
tok if parser.sep.check(tok) => {
drop(peeked);
state = parser.handle_separator(state, inp, leading_spec)?;
continue;
}
_ => peek_span.clone(),
}
}
};
match parser.condition.decide(peeked, emitter)? {
Action::Stop => {
return parser.handle_end(state, inp, &ckp, num_elems, container);
}
Action::Continue => {
state = parser.handle_continue(
state,
inp,
&ckp,
&peek_span,
&mut num_elems,
leading_spec,
container,
)?;
}
}
}
}
}
impl<'c, 'inp, F, SepClassifier, Condition, O, Trailing, Leading, Max, Min, W, L, Ctx, Lang: ?Sized>
SeparatedBy<
&'c mut F,
&'c mut SepClassifier,
&'c mut Condition,
O,
W,
L,
Ctx,
&'c mut SeparatedByOptions<Trailing, Leading, Max, Min>,
Lang,
>
{
pub(in crate::parser) fn handle_separator<'closure>(
&mut self,
mut state: State<L::Token, L::Span>,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
leading_spec: SepFixSpec,
) -> Result<State<L::Token, L::Span>, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
{
let sep_tok = inp
.next()
.expect("peeked token already confirmed there must be a token");
match state {
State::Element => {
state = State::Separator(sep_tok.map_data(|t| t.unwrap_token()));
}
State::Leading(tok) => {
state = State::Leadings(self.handle_leading_state(inp, tok, sep_tok, leading_spec)?);
}
State::Leadings(span) => {
state = State::Leadings(self.handle_leadings_state(inp, span, sep_tok)?);
}
State::Start => {
state = State::Leading(sep_tok.map_data(|t| t.unwrap_token()));
}
State::Separator(tok) => {
state = State::RepeatedSeparator(self.handle_separator_state(inp, tok, sep_tok)?);
}
State::RepeatedSeparator(span) => {
state =
State::RepeatedSeparator(self.handle_repeated_separators_state(inp, span, sep_tok)?);
}
}
Ok(state)
}
#[allow(clippy::too_many_arguments)]
pub(in crate::parser) fn handle_continue<'closure, Container>(
&mut self,
mut state: State<L::Token, L::Span>,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
ckp: &Checkpoint<'inp, 'closure, L>,
peek_span: &L::Span,
num_elems: &mut usize,
leading_spec: SepFixSpec,
container: &mut Container,
) -> Result<State<L::Token, L::Span>, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
W: Window,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Container: SeparatorsContainer<Spanned<L::Token, L::Span>, O>,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
match state {
State::Separator(sep) => {
let element = self.f.parse_input(inp)?;
container.push_separator(sep);
if push(num_elems, container, element).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
container.len(),
Container::capacity(),
))?;
}
state = State::Element;
}
State::Leading(leading_tok) => {
match leading_spec {
SepFixSpec::Deny(_) => {
let (sep_span, sep_token) = leading_tok.into_components();
inp
.emitter()
.emit_unexpected_leading_separator(
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(sep_span, sep_token),
)?;
}
SepFixSpec::Allow(_) | SepFixSpec::Require(_) => {}
}
let element = self.f.parse_input(inp)?;
if push(num_elems, container, element).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
*num_elems,
Container::capacity(),
))?;
}
state = State::Element;
}
State::Leadings(span) => {
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_batch(inp.emitter(), &span)?;
let element = self.f.parse_input(inp)?;
if push(num_elems, container, element).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
*num_elems,
Container::capacity(),
))?;
}
state = State::Element;
}
State::Start => {
match leading_spec {
SepFixSpec::Require(_) => {
let off = peek_span.start();
inp
.emitter()
.emit_missing_leading_separator(
MissingLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(off),
)?;
}
SepFixSpec::Deny(_) | SepFixSpec::Allow(_) => {
}
}
let element = self.f.parse_input(inp)?;
if push(num_elems, container, element).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
*num_elems,
Container::capacity(),
))?;
}
state = State::Element;
}
State::Element => {
let off = peek_span.start();
inp
.emitter()
.emit_missing_separator(MissingSeparatorOf::<'_, SepClassifier, L, Lang>::of(off))?;
let element = self.f.parse_input(inp)?;
if push(num_elems, container, element).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
*num_elems,
Container::capacity(),
))?;
}
state = State::Element;
}
State::RepeatedSeparator(span) => {
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedRepeatedOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_batch(inp.emitter(), &span)?;
if push(num_elems, container, self.f.parse_input(inp)?).is_some() {
let span = inp.span_since(ckp.cursor());
inp.emitter().emit_full_container(FullContainer::of(
span,
*num_elems,
Container::capacity(),
))?;
}
state = State::Element;
}
}
Ok(state)
}
pub(in crate::parser) fn handle_end<'closure, Container>(
&mut self,
state: State<L::Token, L::Span>,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
ckp: &Checkpoint<'inp, 'closure, L>,
num_elems: usize,
container: &mut Container,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
F: ParseInput<'inp, L, O, Ctx, Lang>,
W: Window,
Condition: Decision<'inp, L, Ctx::Emitter, W, Lang>,
SepClassifier: Check<L::Token>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
Container: crate::container::Container<O>,
Trailing: super::TrailingSpec,
Leading: super::LeadingSpec,
Max: super::MaxSpec,
Min: super::MinSpec,
{
let minimum = self.config.minimum();
let maximum = self.config.maximum();
let leading_spec = self.config.leading();
let trailing_spec = self.config.trailing();
Ok(match state {
State::Start => {
let span = inp.span_since(ckp.cursor());
if minimum > 0 {
inp
.emitter()
.emit_too_few(TooFew::of(span.clone(), num_elems, minimum))?;
}
span
}
State::Element => {
let full_span = inp.span_since(ckp.cursor());
if num_elems < minimum {
inp
.emitter()
.emit_too_few(TooFew::of(full_span.clone(), num_elems, minimum))?;
}
if num_elems > maximum {
inp
.emitter()
.emit_too_many(TooMany::of(full_span.clone(), num_elems, maximum))?;
}
if trailing_spec.is_require() {
let off = inp.span().end();
inp
.emitter()
.emit_missing_trailing_separator(
MissingTrailingOf::<'_, SepClassifier, L, Lang>::trailing_of(off),
)?;
}
full_span
}
State::Leading(spanned) => {
let (sep_span, sep_token) = spanned.into_components();
match leading_spec {
SepFixSpec::Deny(_) => {
inp
.emitter()
.emit_unexpected_leading_separator(
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(sep_span, sep_token),
)?;
}
SepFixSpec::Allow(_) | SepFixSpec::Require(_) => {
inp
.emitter()
.emit_missing_element(MissingSyntaxOf::<'_, O, L, Lang>::of(sep_span.end()))?;
}
}
inp.span_since(ckp.cursor())
}
State::Leadings(leadings) => {
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_batch(inp.emitter(), &leadings)?;
let full_span = inp.span_since(ckp.cursor());
if !leading_spec.is_deny() {
inp
.emitter()
.emit_missing_element(MissingSyntaxOf::<'_, O, L, Lang>::of(full_span.end()))?;
}
full_span
}
State::Separator(spanned) => {
let (sep_span, sep_token) = spanned.into_components();
if trailing_spec.is_deny() {
inp
.emitter()
.emit_unexpected_trailing_separator(
UnexpectedTrailingOf::<'_, SepClassifier, L, Lang>::trailing_of(sep_span, sep_token),
)?;
}
let full_span = inp.span_since(ckp.cursor());
let nums = container.len();
if nums < minimum {
inp
.emitter()
.emit_too_few(TooFew::of(full_span.clone(), nums, minimum))?;
}
if nums > maximum {
inp
.emitter()
.emit_too_many(TooMany::of(full_span.clone(), nums, maximum))?;
}
full_span
}
State::RepeatedSeparator(trailings) => {
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedRepeatedOf<'_, SepClassifier, L, Lang>,
Lang,
>>::drop_batch(inp.emitter(), &trailings);
let mut lxr = inp.lexer_at(trailings.start_ref());
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedTrailingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::create_batch(
inp.emitter(),
trailings.clone(),
"trailing separators".into(),
);
while let Some(tok) = lxr.lex() {
let span = lxr.span();
if span.end_ref().ge(trailings.end_ref()) {
break;
}
match tok {
Err(_) => {}
Ok(tok) => {
if self.sep.check(&tok) {
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedTrailingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_to_batch(
inp.emitter(),
&trailings,
Spanned::new(
span.clone(),
UnexpectedTrailingOf::<'_, SepClassifier, L, Lang>::trailing_of(span, tok),
),
)?;
}
}
}
}
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedTrailingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_batch(inp.emitter(), &trailings)?;
inp.span_since(ckp.cursor())
}
})
}
pub(in crate::parser) fn handle_repeated_separators_state<'closure>(
&mut self,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
repeated_separators_errs_id: L::Span,
sep_tok: Spanned<Lexed<'inp, L::Token>, L::Span>,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
{
let (sep_span, sep_token) = sep_tok.into_components();
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedRepeatedOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_to_batch(
inp.emitter(),
&repeated_separators_errs_id,
Spanned::new(
sep_span.clone(),
UnexpectedRepeatedOf::<'_, SepClassifier, L, Lang>::repeated_of(
sep_span.clone(),
sep_token.unwrap_token(),
),
),
)?;
Ok(repeated_separators_errs_id)
}
pub(in crate::parser) fn handle_leadings_state<'closure>(
&mut self,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
leading_errs_id: L::Span,
sep_tok: Spanned<Lexed<'inp, L::Token>, L::Span>,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
{
let (sep_span, sep_tok) = sep_tok.into_components();
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_to_batch(
inp.emitter(),
&leading_errs_id,
Spanned::new(
sep_span.clone(),
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(
sep_span.clone(),
sep_tok.unwrap_token(),
),
),
)?;
Ok(leading_errs_id)
}
pub(in crate::parser) fn handle_leading_state<'closure>(
&mut self,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
tok: Spanned<L::Token, L::Span>,
sep_tok: Spanned<Lexed<'inp, L::Token>, L::Span>,
leading_spec: SepFixSpec,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
{
Ok(match leading_spec {
SepFixSpec::Deny(_) => {
let (tok_span, tok_token) = tok.into_components();
let (sep_span, sep_tok) = sep_tok.into_components();
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::create_batch_with_error(
inp.emitter(),
"leading separators".into(),
Spanned::new(
tok_span.clone(),
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(
tok_span.clone(),
tok_token,
),
),
)?;
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_to_batch(
inp.emitter(),
&tok_span,
Spanned::new(
sep_span.clone(),
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(
sep_span.clone(),
sep_tok.unwrap_token(),
),
),
)?;
tok_span
}
SepFixSpec::Allow(_) | SepFixSpec::Require(_) => {
let (sep_span, sep_tok) = sep_tok.into_components();
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedLeadingOf<'_, SepClassifier, L, Lang>,
Lang,
>>::create_batch_with_error(
inp.emitter(),
"leading separators".into(),
Spanned::new(
sep_span.clone(),
UnexpectedLeadingOf::<'_, SepClassifier, L, Lang>::leading_of(
sep_span.clone(),
sep_tok.unwrap_token(),
),
),
)?;
sep_span
}
})
}
pub(in crate::parser) fn handle_separator_state<'closure>(
&mut self,
inp: &mut InputRef<'inp, 'closure, L, Ctx, Lang>,
tok: Spanned<L::Token, L::Span>,
sep_tok: Spanned<Lexed<'inp, L::Token>, L::Span>,
) -> Result<L::Span, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>
where
'inp: 'closure,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Ctx::Emitter: SeparatedByEmitter<'inp, O, SepClassifier, L, Lang>,
{
let (tok_span, tok_token) = tok.into_components();
let (sep_span, sep_token) = sep_tok.into_components();
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedRepeatedOf<'_, SepClassifier, L, Lang>,
Lang,
>>::create_batch_with_error(
inp.emitter(),
"repeated separator".into(),
Spanned::new(
tok_span.clone(),
UnexpectedRepeatedOf::<'_, SepClassifier, L, Lang>::repeated_of(
tok_span.clone(),
tok_token.clone(),
),
),
)?;
<Ctx::Emitter as BatchEmitter<
'_,
L,
UnexpectedRepeatedOf<'_, SepClassifier, L, Lang>,
Lang,
>>::emit_to_batch(
inp.emitter(),
&tok_span,
Spanned::new(
sep_span.clone(),
UnexpectedRepeatedOf::<'_, SepClassifier, L, Lang>::repeated_of(
sep_span,
sep_token.unwrap_token(),
),
),
)?;
Ok(tok_span)
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn push<C, T>(nums: &mut usize, container: &mut C, item: T) -> Option<T>
where
C: crate::container::Container<T>,
{
match container.push(item) {
None => {
*nums += 1;
None
}
Some(item) => Some(item),
}
}