use crate::source::Chunk;
use crate::{Filter, FilterResult, Lexer, Logos, Skip};
pub trait LexerInternal<'source> {
type Token: Logos<'source>;
fn read<T: Chunk<'source>>(&self) -> Option<T>;
fn read_at<T: Chunk<'source>>(&self, n: usize) -> Option<T>;
#[cfg(not(feature = "forbid_unsafe"))]
unsafe fn read_byte_unchecked(&self, n: usize) -> u8;
#[cfg(feature = "forbid_unsafe")]
fn read_byte(&self, n: usize) -> u8;
fn test<T: Chunk<'source>, F: FnOnce(T) -> bool>(&self, test: F) -> bool;
fn bump_unchecked(&mut self, size: usize);
fn trivia(&mut self);
fn error(&mut self);
fn end(&mut self);
fn set(
&mut self,
token: Result<
Self::Token,
<<Self as LexerInternal<'source>>::Token as Logos<'source>>::Error,
>,
);
}
pub trait CallbackResult<'s, P, T: Logos<'s>> {
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T;
}
pub trait SkipCallbackResult<'s, T: Logos<'s>>
where
Self: Sized,
{
fn into_result(self) -> Result<Skip, T::Error>;
fn construct_skip(self, lex: &mut Lexer<'s, T>) {
match self.into_result() {
Ok(Skip) => {
lex.trivia();
T::lex(lex);
}
Err(e) => lex.set(Err(e)),
}
}
}
impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for P {
#[inline]
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T,
{
lex.set(Ok(c(self)))
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for bool {
#[inline]
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
match self {
true => lex.set(Ok(c(()))),
false => T::make_error(lex),
}
}
}
impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for Option<P> {
#[inline]
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T,
{
match self {
Some(product) => lex.set(Ok(c(product))),
None => T::make_error(lex),
}
}
}
impl<'s, P, E, T: Logos<'s>> CallbackResult<'s, P, T> for Result<P, E>
where
E: Into<T::Error>,
{
#[inline]
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T,
{
match self {
Ok(product) => lex.set(Ok(c(product))),
Err(err) => lex.set(Err(err.into())),
}
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Skip {
#[inline]
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
lex.trivia();
T::lex(lex);
}
}
impl<'s, E, T: Logos<'s>> CallbackResult<'s, (), T> for Result<Skip, E>
where
E: Into<T::Error>,
{
#[inline]
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
match self {
Ok(_) => {
lex.trivia();
T::lex(lex);
}
Err(err) => lex.set(Err(err.into())),
}
}
}
impl<'s, P, T: Logos<'s>> CallbackResult<'s, P, T> for Filter<P> {
#[inline]
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T,
{
match self {
Filter::Emit(product) => lex.set(Ok(c(product))),
Filter::Skip => {
lex.trivia();
T::lex(lex);
}
}
}
}
impl<'s, P, E, T: Logos<'s>> CallbackResult<'s, P, T> for FilterResult<P, E>
where
E: Into<T::Error>,
{
fn construct<Constructor>(self, c: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(P) -> T,
{
match self {
FilterResult::Emit(product) => lex.set(Ok(c(product))),
FilterResult::Skip => {
lex.trivia();
T::lex(lex);
}
FilterResult::Error(err) => lex.set(Err(err.into())),
}
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for T {
#[inline]
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
lex.set(Ok(self))
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Result<T, T::Error> {
#[inline]
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
match self {
Ok(product) => lex.set(Ok(product)),
Err(err) => lex.set(Err(err)),
}
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for Filter<T> {
#[inline]
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
match self {
Filter::Emit(product) => lex.set(Ok(product)),
Filter::Skip => {
lex.trivia();
T::lex(lex);
}
}
}
}
impl<'s, T: Logos<'s>> CallbackResult<'s, (), T> for FilterResult<T, T::Error> {
fn construct<Constructor>(self, _: Constructor, lex: &mut Lexer<'s, T>)
where
Constructor: Fn(()) -> T,
{
match self {
FilterResult::Emit(product) => lex.set(Ok(product)),
FilterResult::Skip => {
lex.trivia();
T::lex(lex);
}
FilterResult::Error(err) => lex.set(Err(err)),
}
}
}
impl<'s, T: Logos<'s>> SkipCallbackResult<'s, T> for () {
fn into_result(self) -> Result<Skip, T::Error> {
Ok(Skip)
}
}
impl<'s, T: Logos<'s>> SkipCallbackResult<'s, T> for Skip {
fn into_result(self) -> Result<Skip, T::Error> {
Ok(self)
}
}
impl<'s, T: Logos<'s>, E> SkipCallbackResult<'s, T> for Result<(), E>
where
E: Into<T::Error>,
{
fn into_result(self) -> Result<Skip, T::Error> {
match self {
Ok(_) => Ok(Skip),
Err(e) => Err(e.into()),
}
}
}
impl<'s, T: Logos<'s>, E> SkipCallbackResult<'s, T> for Result<Skip, E>
where
E: Into<T::Error>,
{
fn into_result(self) -> Result<Skip, T::Error> {
match self {
Ok(skip) => Ok(skip),
Err(e) => Err(e.into()),
}
}
}