use core::fmt;
use core::mem::{replace, take};
use rust_alloc::rc::Rc;
use crate::alloc;
use crate::alloc::prelude::*;
use crate::ast::{Kind, Span, Spanned, ToAst, Token};
use crate::compile::{Error, ErrorKind, Result, WithSpan};
#[cfg(feature = "fmt")]
use crate::fmt::Formatter;
use crate::grammar::ws;
use crate::parse::{Expectation, IntoExpectation};
use crate::shared::FixedVec;
use crate::SourceId;
#[cfg(feature = "std")]
use crate::Sources;
use super::Flavor;
pub(super) type InternalNode<'a> = syntree::Node<'a, Kind, Flavor>;
pub(super) type InternalChildren<'a> = syntree::node::Children<'a, Kind, Flavor>;
pub(crate) trait Ignore<'a> {
fn error(&mut self, error: Error) -> alloc::Result<()>;
fn ignore(&mut self, node: Node<'a>) -> Result<()>;
}
#[derive(Debug, Default)]
pub(crate) struct Tree {
inner: syntree::Tree<Kind, Flavor>,
}
impl Tree {
pub(super) fn new(inner: syntree::Tree<Kind, Flavor>) -> Self {
Self { inner }
}
pub(crate) fn node_at(self: &Rc<Self>, source_id: SourceId, NodeId(id): NodeId) -> NodeAt {
NodeAt {
tree: self.clone(),
source_id,
id,
}
}
pub(crate) fn get(&self, id: syntree::pointer::PointerUsize) -> Option<Node<'_>> {
self.inner.get(id).map(Node::new)
}
pub(crate) fn nodes<const N: usize>(&self) -> Option<[Node<'_>; N]> {
self.fixed_vec(Node::new)?.try_into_inner()
}
fn fixed_vec<'a, const N: usize, T>(
&'a self,
factory: fn(InternalNode<'a>) -> T,
) -> Option<FixedVec<T, N>> {
let mut vec = FixedVec::new();
for node in self
.inner
.children()
.filter(|n| !matches!(n.value(), ws!()))
{
if vec.try_push(factory(node)).is_err() {
return None;
}
}
Some(vec)
}
pub(crate) fn parse_all<'a, P>(&'a self, mut parser: P) -> Result<()>
where
P: FnMut(&mut Stream<'a>) -> Result<()>,
{
for node in self
.inner
.children()
.filter(|n| !matches!(n.value(), ws!()))
{
let mut p = Stream::new(node);
parser(&mut p)?;
p.end()?;
}
Ok(())
}
#[cfg(feature = "fmt")]
pub(crate) fn walk(&self) -> impl Iterator<Item = Node<'_>> {
self.inner.walk().map(Node::new)
}
#[cfg(feature = "std")]
pub(crate) fn print_with_source(
&self,
span: &dyn Spanned,
title: impl fmt::Display,
source: &str,
) -> Result<()> {
use std::io::Write;
let o = std::io::stdout();
let mut o = o.lock();
writeln!(o, "{title}:").with_span(span)?;
for (depth, node) in self.inner.walk().with_depths() {
let n = (depth * 2) as usize;
let data = node.value();
let span = node.span();
if node.has_children() {
writeln!(o, "{:n$}{:?}@{}", "", data, span).with_span(span)?;
} else if let Some(source) = source.get(span.range()) {
writeln!(o, "{:n$}{:?}@{} {:?}", "", data, span, source).with_span(span)?;
} else {
writeln!(o, "{:n$}{:?}@{} +", "", data, span).with_span(span)?;
}
}
Ok(())
}
#[cfg(feature = "std")]
pub(crate) fn print(&self, span: &dyn Spanned, title: impl fmt::Display) -> Result<()> {
use std::io::Write;
let o = std::io::stdout();
let mut o = o.lock();
writeln!(o, "{title}:").with_span(span)?;
for (depth, node) in self.inner.walk().with_depths() {
let n = (depth * 2) as usize;
let data = node.value();
let span = node.span();
if node.has_children() {
writeln!(o, "{:n$}{:?}@{}", "", data, span).with_span(span)?;
} else {
writeln!(o, "{:n$}{:?}@{} +", "", data, span).with_span(span)?;
}
}
Ok(())
}
}
pub(crate) struct StreamBuf<'a> {
stream: Stream<'a>,
}
impl<'a> StreamBuf<'a> {
pub(crate) fn is_eof(&mut self) -> bool {
self.stream.is_eof()
}
pub(crate) fn parse<P, O>(mut self, parser: P) -> Result<O>
where
P: FnOnce(&mut Stream<'a>) -> Result<O>,
{
let out = parser(&mut self.stream)?;
self.stream.end()?;
Ok(out)
}
}
impl Spanned for StreamBuf<'_> {
#[inline]
fn span(&self) -> Span {
self.stream.span()
}
}
impl<'a> Iterator for StreamBuf<'a> {
type Item = Node<'a>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.stream.next()
}
}
impl fmt::Debug for StreamBuf<'_> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.stream.fmt(f)
}
}
pub(crate) struct Stream<'a> {
node: InternalNode<'a>,
iter: Iter<'a>,
peek: Option<InternalNode<'a>>,
}
impl<'a> Stream<'a> {
pub(crate) fn new(node: InternalNode<'a>) -> Self {
Self {
node,
iter: Iter::new(node.first(), node.last()),
peek: None,
}
}
pub(crate) fn ignore(&mut self) {
self.iter = Iter::default();
self.peek = None;
}
pub(crate) fn take_remaining(&mut self) -> StreamBuf<'a> {
StreamBuf {
stream: Stream {
node: self.node,
iter: take(&mut self.iter),
peek: self.peek.take(),
},
}
}
#[cfg(feature = "fmt")]
pub(crate) fn children(&self) -> impl Iterator<Item = Node<'a>> + '_ {
self.iter.clone().map(Node::new)
}
#[cfg(feature = "fmt")]
pub(crate) fn write_remaining(&mut self, o: &mut Formatter<'a>) -> Result<()> {
o.flush_whitespace(false)?;
for node in self.peek.take().into_iter().chain(self.iter.by_ref()) {
o.write_raw(Node::new(node))?;
}
Ok(())
}
#[cfg(feature = "fmt")]
pub(crate) fn fmt_remaining_trimmed(&mut self, o: &mut Formatter<'a>) -> Result<()> {
o.flush_whitespace(false)?;
let mut buf = None;
let mut first = true;
let mut last_was_line = false;
let iter = self.peek.take().into_iter().chain(self.iter.by_ref());
for node in iter {
if node.has_children() {
continue;
}
if matches!(node.value(), Kind::Whitespace) {
buf = Some(Node::new(node));
continue;
}
if !first {
if let Some(buf) = buf.take() {
o.write_raw(buf)?;
}
}
last_was_line = matches!(node.value(), Kind::Comment);
o.write_raw(Node::new(node))?;
first = false;
}
if last_was_line {
o.nl(1)?;
}
Ok(())
}
pub(crate) fn kind(&self) -> Kind {
self.node.value()
}
pub(crate) fn kinds<const N: usize>(&self) -> Option<[Kind; N]> {
self.node().kinds()
}
pub(crate) fn nodes<const N: usize>(&self) -> Option<[Node<'a>; N]> {
self.node().nodes()
}
pub(crate) fn is_eof(&mut self) -> bool {
matches!(self.peek(), Kind::Eof)
}
pub(crate) fn id(&self) -> NodeId {
NodeId(self.node.id())
}
#[inline]
pub(crate) fn node(&self) -> Node<'a> {
Node::new(self.node)
}
pub(crate) fn peek(&mut self) -> Kind {
if let Some(value) = self.peek_node() {
return value.value();
}
Kind::Eof
}
pub(crate) fn peek_span(&mut self) -> Span {
if let Some(node) = self.peek_node() {
return inner_span(node.span());
}
Span::point(self.node.span().end)
}
fn peek_node(&mut self) -> Option<&syntree::Node<Kind, Flavor>> {
if self.peek.is_none() {
if let Some(node) = self.next_node() {
self.peek = Some(node);
}
}
self.peek.as_ref()
}
pub(crate) fn expected_peek(&mut self, expected: impl IntoExpectation) -> Error {
Error::new(
self.peek_span(),
ErrorKind::ExpectedSyntax {
expected: expected.into_expectation(),
actual: self.kind().into_expectation(),
},
)
}
pub(crate) fn expected(&mut self, expected: impl IntoExpectation) -> Error {
Error::new(
self.span(),
ErrorKind::ExpectedSyntax {
expected: expected.into_expectation(),
actual: self.kind().into_expectation(),
},
)
}
pub(crate) fn all<const N: usize>(&mut self, expected: [Kind; N]) -> Result<()> {
for kind in expected {
self.expect(kind)?;
}
Ok(())
}
pub(crate) fn expect(&mut self, expected: Kind) -> Result<Node<'a>> {
let Some(node) = self.next_node() else {
return Err(Error::new(
self.peek_span(),
ErrorKind::UnexpectedEndOfSyntaxWith {
inside: self.kind().into_expectation(),
expected: expected.into_expectation(),
},
));
};
if node.value() != expected {
return Err(Error::new(
inner_span(node.span()),
ErrorKind::ExpectedSyntaxIn {
inside: self.kind().into_expectation(),
expected: expected.into_expectation(),
actual: node.value().into_expectation(),
},
));
}
Ok(Node::new(node))
}
pub(crate) fn pump(&mut self) -> Result<Node<'a>> {
let Some(node) = self.next_node() else {
return Err(Error::new(
self.peek_span(),
ErrorKind::UnexpectedEndOfSyntax {
inside: self.kind().into_expectation(),
},
));
};
Ok(Node::new(node))
}
pub(crate) fn ast<T>(&mut self) -> Result<T>
where
T: ToAst,
{
let Some(node) = self.next_node() else {
return Err(Error::new(
self.peek_span(),
ErrorKind::UnexpectedEndOfSyntaxWith {
inside: self.kind().into_expectation(),
expected: T::into_expectation(),
},
));
};
Node::new(node).ast()
}
pub(crate) fn eat(&mut self, expect: Kind) -> MaybeNode<'a> {
self.eat_matching(|kind| kind == expect)
}
pub(crate) fn try_ast<T>(&mut self) -> Result<Option<T>>
where
T: ToAst,
{
match self.eat_matching(|kind| T::matches(&kind)) {
MaybeNode::Some(node) => Ok(Some(node.ast()?)),
MaybeNode::None => Ok(None),
}
}
pub(crate) fn eat_matching<F>(&mut self, mut filter: F) -> MaybeNode<'a>
where
F: FnMut(Kind) -> bool,
{
if let Some(node) = self.next_node() {
if filter(node.value()) {
return MaybeNode::Some(Node::new(node));
}
self.peek = Some(node);
}
MaybeNode::None
}
pub(crate) fn remaining(
&mut self,
o: &mut dyn Ignore<'a>,
expected: Kind,
) -> Result<Remaining<'a>> {
let mut first = None;
let mut trailing = None::<Span>;
let mut out = MaybeNode::None;
let mut count = 0;
while let Some(node) = self.next_node() {
if node.value() != expected {
if let Some(node) = self.peek.replace(node) {
o.ignore(Node::new(node))?;
}
break;
}
let span = inner_span(node.span());
if first.is_none() {
first = Some(span);
} else {
trailing = Some(trailing.map(|head| head.join(span)).unwrap_or(span));
}
if let MaybeNode::Some(old) = out.replace(Node::new(node)) {
o.ignore(old)?;
}
count += 1;
}
let span = match (first, &out) {
(Some(first), MaybeNode::Some(last)) => first.join(last.span()),
_ => self.peek_span(),
};
Ok(Remaining {
inside: self.kind(),
expected,
span,
trailing,
node: out,
count: Some(count),
})
}
pub(crate) fn one(&mut self, expected: Kind) -> Remaining<'a> {
let node = self.eat(expected);
let span = node.span().unwrap_or_else(|| self.peek_span());
let count = Some(usize::from(node.is_some()));
Remaining {
inside: self.kind(),
expected,
span,
trailing: None,
node,
count,
}
}
pub(super) fn end(mut self) -> Result<()> {
if let Some(node) = self.next_node() {
let inside = self.kind();
let span = match self.iter.last() {
Some(last) => node.span().join(last.span()),
None => *node.span(),
};
return Err(Error::new(
inner_span(&span),
ErrorKind::ExpectedSyntaxEnd {
inside: inside.into_expectation(),
actual: node.value().into_expectation(),
},
));
}
Ok(())
}
pub(crate) fn remaining_span(&mut self) -> Option<Span> {
let head = *self.peek_node()?.span();
if let Some(last) = self.iter.peek_back() {
Some(Span::new(head.start, last.span().end))
} else {
Some(Span::new(head.start, head.end))
}
}
pub(crate) fn span(&self) -> Span {
inner_span(self.node.span())
}
#[cfg(feature = "fmt")]
pub(crate) fn next_with_ws(&mut self) -> Option<Node<'a>> {
if let Some(node) = self.peek.take() {
return Some(Node::new(node));
}
self.iter.next().map(Node::new)
}
fn next_node(&mut self) -> Option<InternalNode<'a>> {
if let Some(node) = self.peek.take() {
return Some(node);
}
self.iter.find(|node| !matches!(node.value(), ws!()))
}
fn next_back_node(&mut self) -> Option<InternalNode<'a>> {
if let Some(node) = self.iter.rfind(|node| !matches!(node.value(), ws!())) {
return Some(node);
}
self.peek.take()
}
}
impl fmt::Debug for Stream<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Stream").finish_non_exhaustive()
}
}
impl Spanned for Stream<'_> {
#[inline]
fn span(&self) -> Span {
Stream::span(self)
}
}
impl<'a> Iterator for Stream<'a> {
type Item = Node<'a>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.next_node().map(Node::new)
}
}
impl DoubleEndedIterator for Stream<'_> {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.next_back_node().map(Node::new)
}
}
#[derive(Debug)]
pub(crate) struct NodeId(syntree::pointer::PointerUsize);
#[derive(Debug, TryClone, Clone)]
#[try_clone(crate)]
pub(crate) struct NodeAt {
tree: Rc<Tree>,
#[try_clone(copy)]
source_id: SourceId,
#[try_clone(copy)]
id: syntree::pointer::PointerUsize,
}
impl NodeAt {
pub(crate) fn tree(&self) -> &Rc<Tree> {
&self.tree
}
pub(crate) fn parse<'a, P, O>(&'a self, parser: P) -> Result<O>
where
P: FnOnce(&mut Stream<'a>) -> Result<O>,
{
let Some(node) = self.tree.get(self.id) else {
return Err(Error::msg(
Span::empty(),
try_format!("missing node {}", self.id.get()),
));
};
node.parse(parser)
}
pub(crate) fn parse_id<'a, P, O>(&'a self, NodeId(id): NodeId, parser: P) -> Result<O>
where
P: FnOnce(&mut Stream<'a>) -> Result<O>,
{
let Some(node) = self.tree.get(id) else {
return Err(Error::msg(
Span::empty(),
try_format!("missing node {}", self.id.get()),
));
};
node.parse(parser)
}
#[cfg(feature = "std")]
pub(crate) fn print_with_sources(
&self,
title: impl fmt::Display,
sources: &Sources,
) -> Result<()> {
use std::io::Write;
let o = std::io::stdout();
let mut o = o.lock();
let Some(node) = self.tree.get(self.id) else {
return Err(Error::msg(
Span::empty(),
try_format!("missing node {}", self.id.get()),
));
};
let source = sources.get(self.source_id);
writeln!(o, "{title}:").with_span(Span::empty())?;
for (depth, node) in node.inner.walk().with_depths() {
if depth < 0 {
break;
}
let n = (depth * 2) as usize;
let data = node.value();
let span = inner_span(node.span());
if node.has_children() {
writeln!(o, "{:n$}{:?}@{}", "", data, span).with_span(span)?;
} else if let Some(source) = source.and_then(|s| s.get(span.range())) {
writeln!(o, "{:n$}{:?}@{} {:?}", "", data, span, source).with_span(span)?;
} else {
writeln!(o, "{:n$}{:?}@{} +", "", data, span).with_span(span)?;
}
}
Ok(())
}
}
impl Spanned for NodeAt {
fn span(&self) -> Span {
let Some(node) = self.tree.get(self.id) else {
return Span::empty();
};
node.span()
}
}
#[derive(Clone)]
pub(crate) struct Node<'a> {
inner: InternalNode<'a>,
}
impl<'a> Node<'a> {
#[inline]
pub(super) fn new(inner: InternalNode<'a>) -> Self {
Self { inner }
}
pub(crate) fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub(crate) fn token(&self) -> Token {
inner_token(self.inner)
}
pub(crate) fn kind(&self) -> Kind {
self.inner.value()
}
pub(crate) fn walk(&self) -> impl Iterator<Item = Node<'a>> {
self.inner.walk().inside().map(Node::new)
}
pub(crate) fn node_at(&self, source_id: SourceId, tree: Rc<Tree>) -> NodeAt {
NodeAt {
tree,
source_id,
id: self.inner.id(),
}
}
pub(crate) fn replace(&self, kind: Kind) -> Kind {
self.inner.replace(kind)
}
pub(crate) fn children(&self) -> impl DoubleEndedIterator<Item = Node<'a>> + '_ {
self.inner.children().map(Node::new)
}
pub(crate) fn internal_children(&self) -> InternalChildren<'a> {
self.inner.children()
}
pub(crate) fn fixed_vec<const N: usize, T>(
&self,
factory: fn(InternalNode<'a>) -> T,
) -> Option<FixedVec<T, N>> {
let mut vec = FixedVec::new();
for node in self
.inner
.children()
.filter(|n| !matches!(n.value(), ws!()))
{
if vec.try_push(factory(node)).is_err() {
return None;
}
}
Some(vec)
}
pub(crate) fn kinds<const N: usize>(&self) -> Option<[Kind; N]> {
self.fixed_vec(|n| n.value())?.try_into_inner()
}
pub(crate) fn tokens<const N: usize>(&self) -> Option<FixedVec<Token, N>> {
self.fixed_vec(inner_token)
}
pub(crate) fn nodes<const N: usize>(&self) -> Option<[Node<'a>; N]> {
self.fixed_vec(Node::new)?.try_into_inner()
}
pub(crate) fn ast<T>(self) -> Result<T>
where
T: ToAst,
{
T::to_ast(self.span(), self.kind())
}
#[cfg(feature = "fmt")]
pub(crate) fn unsupported(&self, expected: impl IntoExpectation) -> Error {
Error::new(
self.span(),
ErrorKind::ExpectedSyntax {
expected: expected.into_expectation(),
actual: self.kind().into_expectation(),
},
)
}
#[cfg(feature = "fmt")]
pub(crate) fn fmt(self, o: &mut Formatter<'a>) -> Result<()> {
o.write_owned(self)
}
#[cfg(feature = "fmt")]
pub(crate) fn ignore(self, o: &mut Formatter<'a>) -> Result<()> {
o.ignore(self)
}
#[cfg(feature = "fmt")]
pub(crate) fn walk_from(&self) -> impl Iterator<Item = Node<'a>> + '_ {
self.inner.walk_from().map(Node::new)
}
#[inline]
pub(crate) fn parse<P, O>(self, parser: P) -> Result<O>
where
P: FnOnce(&mut Stream<'a>) -> Result<O>,
{
self.into_stream().parse(parser)
}
pub(crate) fn into_stream(self) -> StreamBuf<'a> {
StreamBuf {
stream: Stream::new(self.inner),
}
}
pub(crate) fn span(&self) -> Span {
inner_span(self.inner.span())
}
#[cfg(feature = "fmt")]
pub(crate) fn is_whitespace(&self) -> bool {
matches!(self.inner.value(), Kind::Whitespace)
}
#[cfg(feature = "fmt")]
pub(crate) fn has_children(&self) -> bool {
self.inner.has_children()
}
pub(crate) fn find(&self, kind: Kind) -> Option<Node<'a>> {
self.inner
.children()
.find(|n| n.value() == kind)
.map(Node::new)
}
pub(crate) fn expected(&self, expected: impl IntoExpectation) -> Error {
Error::new(
self.span(),
ErrorKind::ExpectedSyntax {
expected: expected.into_expectation(),
actual: self.kind().into_expectation(),
},
)
}
}
#[inline]
pub(super) fn inner_token(node: InternalNode<'_>) -> Token {
Token {
span: inner_span(node.span()),
kind: node.value(),
}
}
#[inline]
fn inner_span(span: &syntree::Span<u32>) -> Span {
Span::new(span.start, span.end)
}
impl IntoExpectation for Node<'_> {
#[inline]
fn into_expectation(self) -> Expectation {
self.inner.value().into_expectation()
}
}
impl Spanned for Node<'_> {
#[inline]
fn span(&self) -> Span {
Node::span(self)
}
}
impl fmt::Debug for Node<'_> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Node")
.field("kind", &self.kind())
.field("span", &self.span())
.finish()
}
}
#[must_use = "Remaining nodes must be consumed to capture all whitespace and comments"]
pub(crate) struct Remaining<'a> {
inside: Kind,
expected: Kind,
span: Span,
trailing: Option<Span>,
node: MaybeNode<'a>,
count: Option<usize>,
}
impl<'a> Remaining<'a> {
pub(crate) fn trailing(&self) -> Option<Span> {
self.trailing
}
pub(crate) fn exactly_one(self, o: &mut dyn Ignore<'a>) -> Result<()> {
if let MaybeNode::Some(node) = self.node {
o.ignore(node)?;
}
let Some(count) = self.count else {
return Ok(());
};
if count == 0 {
let result = o.error(Error::new(
self.span,
ErrorKind::ExpectedOne {
inside: self.inside.into_expectation(),
expected: self.expected.into_expectation(),
},
));
result.with_span(self.span)?;
}
if let Some(span) = self.trailing {
let result = o.error(Error::new(
span,
ErrorKind::ExpectedAtMostOne {
inside: self.inside.into_expectation(),
expected: self.expected.into_expectation(),
count,
},
));
result.with_span(self.span)?;
}
Ok(())
}
pub(crate) fn at_most_one(self, o: &mut dyn Ignore<'a>) -> Result<()> {
if let MaybeNode::Some(node) = self.node {
o.ignore(node)?;
}
let Some(count) = self.count else {
return Ok(());
};
if let Some(span) = self.trailing {
let result = o.error(Error::new(
span,
ErrorKind::ExpectedAtMostOne {
inside: self.inside.into_expectation(),
expected: self.expected.into_expectation(),
count,
},
));
result.with_span(self.span)?;
}
Ok(())
}
pub(crate) fn at_least_one(self, o: &mut dyn Ignore<'a>) -> Result<()> {
if let MaybeNode::Some(node) = self.node {
o.ignore(node)?;
}
if matches!(self.count, Some(0)) {
let result = o.error(Error::new(
self.span,
ErrorKind::ExpectedAtLeastOne {
inside: self.inside.into_expectation(),
expected: self.expected.into_expectation(),
},
));
result.with_span(self.span)?;
}
Ok(())
}
#[inline]
pub(crate) fn is_present(&self) -> bool {
self.node.is_some()
}
#[inline]
pub(crate) fn is_absent(&self) -> bool {
self.node.is_none()
}
#[cfg(feature = "fmt")]
pub(crate) fn fmt(self, o: &mut Formatter<'a>) -> Result<bool> {
self.write_if(o, true)
}
#[cfg(feature = "fmt")]
pub(crate) fn write_if(mut self, o: &mut Formatter<'a>, needed: bool) -> Result<bool> {
if self.count.is_none() {
return Ok(false);
}
if let MaybeNode::Some(node) = self.node.take() {
o.write_owned(node)?;
} else if needed {
o.lit(self.lit()?)?;
}
Ok(true)
}
#[cfg(feature = "fmt")]
pub(crate) fn write_only_if(mut self, o: &mut Formatter<'a>, needed: bool) -> Result<()> {
if let MaybeNode::Some(node) = self.node.take() {
if needed {
o.write_owned(node)?;
} else {
o.ignore(node)?;
}
} else if needed {
o.lit(self.lit()?)?;
}
Ok(())
}
pub(crate) fn ignore(self, o: &mut dyn Ignore<'a>) -> Result<bool> {
if self.count.is_none() {
return Ok(false);
}
if let MaybeNode::Some(node) = self.node {
o.ignore(node)?;
}
Ok(true)
}
#[cfg(feature = "fmt")]
fn lit(&self) -> Result<&'static str> {
let lit = match self.expected.into_expectation() {
Expectation::Keyword(lit) => lit,
Expectation::Delimiter(lit) => lit,
Expectation::Punctuation(lit) => lit,
expectation => {
return Err(Error::new(
self.span,
ErrorKind::UnsupportedDelimiter { expectation },
));
}
};
Ok(lit)
}
}
impl Default for Remaining<'_> {
#[inline]
fn default() -> Self {
Self {
inside: Kind::Root,
expected: Kind::Eof,
span: Span::empty(),
trailing: None,
node: MaybeNode::None,
count: None,
}
}
}
#[derive(Default, Clone)]
struct Iter<'a> {
first: Option<InternalNode<'a>>,
last: Option<InternalNode<'a>>,
}
impl<'a> Iter<'a> {
fn new(first: Option<InternalNode<'a>>, last: Option<InternalNode<'a>>) -> Self {
Self { first, last }
}
fn peek_back(&self) -> Option<InternalNode<'a>> {
self.last
}
}
impl<'a> Iterator for Iter<'a> {
type Item = InternalNode<'a>;
fn next(&mut self) -> Option<Self::Item> {
let node = self.first.take()?;
if Some(node.id()) == self.last.map(|n| n.id()) {
self.last = None;
} else {
self.first = node.next();
}
Some(node)
}
}
impl DoubleEndedIterator for Iter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
let node = self.last.take()?;
if Some(node.id()) == self.first.map(|n| n.id()) {
self.first = None;
} else {
self.last = node.prev();
}
Some(node)
}
}
#[derive(Default)]
pub(crate) enum MaybeNode<'a> {
Some(Node<'a>),
#[default]
None,
}
impl<'a> MaybeNode<'a> {
pub(crate) fn is_some(&self) -> bool {
matches!(self, MaybeNode::Some(..))
}
pub(crate) fn is_none(&self) -> bool {
matches!(self, MaybeNode::None)
}
#[cfg(feature = "fmt")]
pub(crate) fn fmt(self, o: &mut Formatter<'a>) -> Result<()> {
match self {
MaybeNode::Some(node) => node.fmt(o),
MaybeNode::None => Ok(()),
}
}
#[cfg(feature = "fmt")]
pub(crate) fn and_then<O>(self, f: impl FnOnce(Node<'a>) -> Result<O>) -> Result<Option<O>> {
match self {
MaybeNode::Some(node) => Ok(Some(f(node)?)),
MaybeNode::None => Ok(None),
}
}
#[cfg(feature = "fmt")]
pub(crate) fn take(&mut self) -> Self {
take(self)
}
pub(crate) fn replace(&mut self, node: Node<'a>) -> Self {
replace(self, MaybeNode::Some(node))
}
pub(crate) fn span(&self) -> Option<Span> {
match self {
MaybeNode::Some(node) => Some(node.span()),
MaybeNode::None => None,
}
}
pub(crate) fn ast<T>(self) -> Result<Option<T>>
where
T: ToAst,
{
match self {
MaybeNode::Some(node) => node.ast().map(Some),
MaybeNode::None => Ok(None),
}
}
pub(crate) fn parse<P, O>(self, parser: P) -> Result<Option<O>>
where
P: FnOnce(&mut Stream<'a>) -> Result<O>,
{
match self {
MaybeNode::Some(node) => node.parse(parser).map(Some),
MaybeNode::None => Ok(None),
}
}
}