I'm making a parser:
pub enum TokenContent {
Breaks,
Heading(usize),
CodeFence(usize),
Text,
NewLine(NewLineType),
}
pub struct Token {
pub content: TokenContent,
pub range: Range<usize>,
}
pub struct Parser<'raw> {
stream: TokenStream<'raw>,
}
token_stream
is a data structure that can provide a sequence of tokens from the lexer:
pub struct TokenStream<'raw> {
raw: &'raw str, // track the str to parse
source: Peekable<TokenIter<'raw>>, // iterator of token
}
I want to implement a method on TokenStream
named take_until
to return a new Iterator
from the current position of TokenStream.source
to the specific stop
symbol:
impl<'raw> TokenStream<'raw> {
pub fn take_until(&self, stop: TokenContent) -> impl Iterator<Item = Token> + 'raw {
self.source.peek_while(move |x| x.content != stop)
}
}
Meet the error:
cannot move out of `self.source` which is behind a mutable reference
move occurs because `self.source` has type `Peekable<LexerIntoIterator<'_>>`, which does not implement the `Copy` traitrustcE0507
How to implement take_until
borrow the immutable reference of TokenStream
then I can call another method on TokenStream
after I call take_until
? Is there some Rust-native way to do it?
My peek_while.rs:
use std::{
iter::Peekable
};
pub struct PeekWhile<I: Iterator, P> {
iter: Peekable<I>,
predicate: P,
}
impl<I: Iterator, P> PeekWhile<I, P> {
pub fn new(iter: I, predicate: P) -> Self {
Self {
iter: iter.peekable(),
predicate,
}
}
}
impl<I: Iterator, P> Iterator for PeekWhile<I, P>
where
P: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
let x = self.iter.peek()?;
if (self.predicate)(&x) {
Some(self.iter.next().unwrap())
} else {
None
}
}
}
pub trait PeekWhileExt: Iterator {
fn peek_while<P>(self, predicate: P) -> PeekWhile<Self, P>
where
P: FnMut(&<Self as Iterator>::Item) -> bool,
Self: Sized,
{
PeekWhile::new(self, predicate)
}
}
impl<I: Iterator> PeekWhileExt for I {}
(self, predicate: P)` instead of `fn peek_while
(&self, predicate: P)` (note the reference before `self`)
– tungli Aug 04 '21 at 15:49