use core::{convert::Infallible, fmt, hash::Hash, ops::AddAssign};
use mayber::Maybe;
use crate::utils::{SimpleSpan, Spanned};
pub(crate) use input::Input;
#[cfg(feature = "logos")]
pub use self::logos::LogosLexer;
pub use cache::*;
pub use checkpoint::Checkpoint;
pub use cursor::Cursor;
pub use input::InputContext;
pub use input_ref::InputRef;
pub use source::Source;
#[cfg(feature = "logos")]
pub use token::Logos;
pub use token::{
DelimiterToken, IdentifierToken, KeywordToken, Lexed, LitToken, OperatorToken, PunctuatorToken,
Token,
};
pub use peek::Peeked;
pub mod token;
pub mod source;
mod cache;
mod checkpoint;
mod cursor;
mod input;
mod input_ref;
#[cfg(feature = "logos")]
mod logos;
mod peek;
pub trait IntoLexer<'inp, T: ?Sized> {
type Lexer;
fn into_lexer(self) -> Self::Lexer
where
Self: 'inp,
T: Token<'inp>;
}
impl<'inp, T, L> IntoLexer<'inp, T> for L
where
T: Token<'inp>,
L: Lexer<'inp, Token = T>,
{
type Lexer = L;
#[cfg_attr(not(tarpaulin), inline(always))]
fn into_lexer(self) -> Self::Lexer {
self
}
}
pub trait Lexer<'inp>: 'inp {
type State: State;
type Source: source::Source<Self::Offset> + ?Sized;
type Token: Token<'inp>;
type Span: fmt::Debug + Span<Offset = Self::Offset> + Ord + Clone + Hash;
type Offset: Default + fmt::Debug + Ord + Clone + Hash;
fn new(src: &'inp Self::Source) -> Self
where
Self::State: Default;
fn with_state(src: &'inp Self::Source, state: Self::State) -> Self;
fn check(&self) -> Result<(), <Self::Token as Token<'inp>>::Error>;
fn state(&self) -> &Self::State;
fn state_mut(&mut self) -> &mut Self::State;
fn into_state(self) -> Self::State;
fn source(&self) -> &'inp Self::Source;
fn span(&self) -> Self::Span;
fn slice(&self) -> <Self::Source as Source<Self::Offset>>::Slice<'inp>;
fn lex(&mut self) -> Option<Result<Self::Token, <Self::Token as Token<'inp>>::Error>>;
fn bump(&mut self, n: &Self::Offset);
}
pub trait Lexable<I, Error> {
fn lex(input: I) -> Result<Self, Error>
where
Self: Sized;
}
pub trait State: core::fmt::Debug + Clone {
type Error: Clone;
fn check(&self) -> Result<(), Self::Error>;
}
impl State for () {
type Error = ();
#[cfg_attr(not(tarpaulin), inline(always))]
fn check(&self) -> Result<(), Self::Error> {
Ok(())
}
}
impl State for Infallible {
type Error = Infallible;
#[cfg_attr(not(tarpaulin), inline(always))]
fn check(&self) -> Result<(), Self::Error> {
Ok(())
}
}
pub type CachedTokenOf<
'a,
L,
T = Lexed<'a, <L as Lexer<'a>>::Token>,
Span = <L as Lexer<'a>>::Span,
> = CachedToken<T, <L as Lexer<'a>>::State, Span>;
pub type CachedTokenRefOf<
'r,
'a,
L,
T = Lexed<'a, <L as Lexer<'a>>::Token>,
Span = <L as Lexer<'a>>::Span,
> = CachedToken<&'r T, &'r <L as Lexer<'a>>::State, &'r Span>;
pub type MaybeRefCachedTokenOf<
'r,
'a,
L,
T = Lexed<'a, <L as Lexer<'a>>::Token>,
Span = <L as Lexer<'a>>::Span,
> = Maybe<CachedTokenRefOf<'r, 'a, L, T, Span>, CachedTokenOf<'a, L, T, Span>>;
pub struct CachedToken<T, State, Span> {
token: Spanned<T, Span>,
state: State,
}
impl<T, State, Span> Clone for CachedToken<T, State, Span>
where
State: Clone,
Span: Clone,
T: Clone,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn clone(&self) -> Self {
Self {
token: self.token.clone(),
state: self.state.clone(),
}
}
}
impl<T, State, Span> CachedToken<T, State, Span> {
#[cfg_attr(not(tarpaulin), inline(always))]
const fn new(token: Spanned<T, Span>, state: State) -> Self {
Self { token, state }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn token(&self) -> Spanned<&T, &Span> {
self.token.as_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_token(self) -> Spanned<T, Span> {
self.token
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn as_ref(&self) -> CachedToken<&T, &State, &Span> {
CachedToken {
token: self.token.as_ref(),
state: &self.state,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn map_token<U, F>(self, f: F) -> CachedToken<U, State, Span>
where
F: FnOnce(T) -> U,
{
CachedToken {
token: self.token.map_data(f),
state: self.state,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn state(&self) -> &State {
&self.state
}
#[cfg_attr(not(tarpaulin), inline(always))]
#[allow(clippy::type_complexity)]
pub fn into_components(self) -> (Spanned<T, Span>, State) {
(self.token, self.state)
}
}
pub trait Span {
type Offset: Ord + Clone + Hash;
fn new(start: Self::Offset, end: Self::Offset) -> Self;
fn into_range(self) -> core::ops::Range<Self::Offset>
where
Self: Sized;
#[cfg_attr(not(tarpaulin), inline(always))]
fn start(&self) -> Self::Offset {
self.start_ref().clone()
}
fn start_ref(&self) -> &Self::Offset;
fn start_mut(&mut self) -> &mut Self::Offset;
#[cfg_attr(not(tarpaulin), inline(always))]
fn end(&self) -> Self::Offset {
self.end_ref().clone()
}
fn end_ref(&self) -> &Self::Offset;
fn end_mut(&mut self) -> &mut Self::Offset;
fn bump(&mut self, n: &Self::Offset);
}
impl Span for core::ops::Range<usize> {
type Offset = usize;
#[cfg_attr(not(tarpaulin), inline(always))]
fn new(start: Self::Offset, end: Self::Offset) -> Self {
start..end
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn start_ref(&self) -> &Self::Offset {
&self.start
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn end_ref(&self) -> &Self::Offset {
&self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn start_mut(&mut self) -> &mut Self::Offset {
&mut self.start
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn end_mut(&mut self) -> &mut Self::Offset {
&mut self.end
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn bump(&mut self, n: &Self::Offset) {
self.end += *n;
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn into_range(self) -> core::ops::Range<Self::Offset> {
self.start..self.end
}
}
impl<O> Span for SimpleSpan<O>
where
O: Ord + Clone + Hash + for<'a> AddAssign<&'a O>,
{
type Offset = O;
#[cfg_attr(not(tarpaulin), inline(always))]
fn new(start: Self::Offset, end: Self::Offset) -> Self {
SimpleSpan::new(start, end)
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn start_ref(&self) -> &Self::Offset {
self.start_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn start_mut(&mut self) -> &mut Self::Offset {
self.start_mut()
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn end_ref(&self) -> &Self::Offset {
self.end_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn end_mut(&mut self) -> &mut Self::Offset {
self.end_mut()
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn bump(&mut self, n: &Self::Offset) {
self.bump(n);
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn into_range(self) -> core::ops::Range<Self::Offset> {
self.start..self.end
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct BlackHole;
impl<O> From<O> for BlackHole
where
(): From<O>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(_: O) -> Self {
BlackHole
}
}
#[cfg(test)]
pub(crate) struct DummyLexer;
#[cfg(test)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, derive_more::Display)]
#[display("DummyToken")]
pub(crate) struct DummyToken;
#[cfg(test)]
const _: () = {
impl Token<'_> for DummyToken {
type Kind = Self;
type Error = ();
#[cfg_attr(not(tarpaulin), inline(always))]
fn kind(&self) -> Self::Kind {
*self
}
#[cfg_attr(not(tarpaulin), inline(always))]
fn is_trivia(&self) -> bool {
true
}
}
impl PunctuatorToken<'_> for DummyToken {}
impl LitToken<'_> for DummyToken {}
impl OperatorToken<'_> for DummyToken {}
impl<'inp> Lexer<'inp> for DummyLexer {
type State = ();
type Source = str;
type Token = DummyToken;
type Span = SimpleSpan;
type Offset = usize;
fn new(_: &'inp Self::Source) -> Self
where
Self::State: Default,
{
todo!()
}
fn with_state(_: &'inp Self::Source, _: Self::State) -> Self {
todo!()
}
fn check(&self) -> Result<(), <Self::Token as Token<'inp>>::Error> {
todo!()
}
fn state(&self) -> &Self::State {
todo!()
}
fn state_mut(&mut self) -> &mut Self::State {
todo!()
}
fn into_state(self) -> Self::State {
todo!()
}
fn source(&self) -> &'inp Self::Source {
todo!()
}
fn span(&self) -> Self::Span {
todo!()
}
fn slice(&self) -> <Self::Source as Source<Self::Offset>>::Slice<'inp> {
todo!()
}
fn lex(&mut self) -> Option<Result<Self::Token, <Self::Token as Token<'inp>>::Error>> {
todo!()
}
fn bump(&mut self, _: &Self::Offset) {
todo!()
}
}
};