use core::{marker::PhantomData, ops::AddAssign};
use crate::{
Lexer, Token,
error::token::{Leading, Separator, Trailing},
utils::{Expected, Message},
};
pub use missing_leading::*;
pub use missing_trailing::*;
mod missing_leading;
mod missing_trailing;
pub type MissingSeparatorOf<'inp, Sep, L, Lang = ()> = MissingToken<
'inp,
<<L as Lexer<'inp>>::Token as Token<'inp>>::Kind,
<L as Lexer<'inp>>::Offset,
Separator<Sep, Lang>,
>;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MissingToken<'a, Kind, O = usize, Lang: ?Sized = ()> {
offset: O,
expected: Option<Expected<'a, Kind>>,
message: Option<Message>,
_lang: PhantomData<Lang>,
}
impl<Kind, O, Data> MissingToken<'_, Kind, O, Trailing<Data>> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn trailing(offset: O) -> Self {
Self::trailing_of(offset)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn trailing_with_message(offset: O, message: Message) -> Self {
Self::trailing_with_message_of(offset, message)
}
}
impl<Kind, O, Data, Lang> MissingToken<'_, Kind, O, Leading<Data, Lang>> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn leading(offset: O) -> Self {
Self::leading_of(offset)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn leading_with_message(offset: O, message: Message) -> Self {
Self::leading_with_message_of(offset, message)
}
}
impl<Kind, O, Data, Lang: ?Sized> MissingToken<'_, Kind, O, Trailing<Data, Lang>> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn trailing_of(offset: O) -> Self {
Self::of(offset)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn trailing_with_message_of(offset: O, message: Message) -> Self {
Self::with_message_of(offset, message)
}
}
impl<Kind, O, Data, Lang: ?Sized> MissingToken<'_, Kind, O, Leading<Data, Lang>> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn leading_of(offset: O) -> Self {
Self::of(offset)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn leading_with_message_of(offset: O, message: Message) -> Self {
Self::with_message_of(offset, message)
}
}
impl<Kind, O> MissingToken<'_, Kind, O> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(offset: O) -> Self {
Self::of(offset)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_message(offset: O, message: Message) -> Self {
Self::with_message_of(offset, message)
}
}
impl<'a, Kind, O, Lang: ?Sized> MissingToken<'a, Kind, O, Lang> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub(super) const fn new_in(
offset: O,
expected: Option<Expected<'a, Kind>>,
message: Option<Message>,
) -> Self {
Self {
offset,
expected,
message,
_lang: PhantomData,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn of(offset: O) -> Self {
Self::new_in(offset, None, None)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_message_of(offset: O, message: Message) -> Self {
Self::new_in(offset, None, Some(message))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn with_expected(offset: O, expected: Expected<'a, Kind>) -> Self {
Self::new_in(offset, Some(expected), None)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn expected_one(offset: O, expected: Kind) -> Self {
Self::with_expected(offset, Expected::one(expected))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn expected_one_with_found(offset: O, expected: Kind) -> Self {
Self::new_in(offset, Some(Expected::one(expected)), None)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn expected_one_of(offset: O, expected: &'static [Kind]) -> Self {
Self::with_expected(offset, Expected::one_of(expected))
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn expected_one_of_with_found(offset: O, expected: &'static [Kind]) -> Self {
Self::new_in(offset, Some(Expected::one_of(expected)), None)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn offset(&self) -> O
where
O: Copy,
{
self.offset
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn offset_ref(&self) -> &O {
&self.offset
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn offset_mut(&mut self) -> &mut O {
&mut self.offset
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn message(&self) -> Option<&Message> {
self.message.as_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn message_mut(&mut self) -> Option<&mut Message> {
self.message.as_mut()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn expected(&self) -> Option<&Expected<'a, Kind>> {
self.expected.as_ref()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn bump(&mut self, offset: &O)
where
O: for<'b> AddAssign<&'b O>,
{
self.offset += offset;
}
pub fn map_expected<F, Kind2>(self, f: F) -> MissingToken<'a, Kind2, O, Lang>
where
F: FnOnce(Expected<'a, Kind>) -> Expected<'a, Kind2>,
{
MissingToken {
offset: self.offset,
expected: self.expected.map(f),
message: self.message,
_lang: PhantomData,
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn into_components(self) -> (O, Option<Expected<'a, Kind>>, Option<Message>) {
(self.offset, self.expected, self.message)
}
}
impl<'a, Kind, O, Lang: ?Sized> From<MissingToken<'a, Kind, O, Lang>> for () {
#[cfg_attr(not(tarpaulin), inline(always))]
fn from(_: MissingToken<'a, Kind, O, Lang>) -> Self {}
}
impl<Kind, O, Lang: ?Sized> MissingToken<'_, Kind, O, Lang> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn debug_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
where
O: core::fmt::Debug,
Kind: core::fmt::Debug,
{
f.debug_struct("MissingToken")
.field("offset", &self.offset)
.field("expected", &self.expected)
.field("message", &self.message)
.finish()
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub fn display_fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
where
O: core::fmt::Display,
Kind: core::fmt::Display,
{
match &self.expected {
Some(expected) => match &self.message {
Some(message) => write!(
f,
"missing token at {}, expected {}, message: {}",
self.offset, expected, message
),
None => write!(f, "missing token at {}, expected {}", self.offset, expected),
},
None => match &self.message {
Some(message) => write!(f, "missing token at {}, message: {}", self.offset, message),
None => write!(f, "missing token at {}", self.offset),
},
}
}
}