use std::cell::RefCell;
use proc_macro2::Span;
use syn::buffer::Cursor;
use error;
use parse::Error;
use token::Token;
pub struct Lookahead1<'a> {
scope: Span,
cursor: Cursor<'a>,
comparisons: RefCell<Vec<String>>,
}
impl<'a> Lookahead1<'a> {
#[doc(hidden)]
pub fn new(scope: Span, cursor: Cursor<'a>) -> Self {
Lookahead1 {
scope: scope,
cursor: cursor,
comparisons: RefCell::new(Vec::new()),
}
}
pub fn peek<T: Peek>(&self, token: T) -> bool {
let _ = token;
if T::Token::peek(self) {
return true;
}
self.comparisons.borrow_mut().push(T::Token::display());
false
}
pub fn error(self) -> Error {
let message = format!("expected one of {:?}", self.comparisons.borrow());
error::new_at(self.scope, self.cursor, message)
}
}
pub trait Peek: private::Sealed {
#[doc(hidden)]
type Token: Token;
}
impl<F: FnOnce(Span) -> T, T: Token> Peek for F {
type Token = T;
}
#[doc(hidden)]
pub fn is_token(lookahead: &Lookahead1, repr: &'static str) -> bool {
if let Some((token, _rest)) = lookahead.cursor.token_tree() {
token.to_string() == repr
} else {
false
}
}
mod private {
use super::{Span, Token};
pub trait Sealed {}
impl<F, T: Token> Sealed for F where F: FnOnce(Span) -> T {}
}