use crate::debug::{restrict, DebugWidth};
use crate::parser_error::ParserError;
use crate::spans::SpanFragment;
use crate::{Code, ErrOrNomErr, KParseError};
use nom::error::ErrorKind;
use nom::{InputIter, InputLength, InputTake};
use std::error::Error;
use std::fmt;
use std::fmt::{Debug, Display};
pub struct TokenizerError<C, I> {
pub code: C,
pub span: I,
}
impl<C, I> ErrOrNomErr for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
type WrappedError = TokenizerError<C, I>;
fn wrap(self) -> nom::Err<Self::WrappedError> {
nom::Err::Error(self)
}
}
impl<C, I> ErrOrNomErr for nom::Err<TokenizerError<C, I>>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
type WrappedError = TokenizerError<C, I>;
fn wrap(self) -> nom::Err<Self::WrappedError> {
self
}
}
impl<C, I> KParseError<C, I> for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
type WrappedError = TokenizerError<C, I>;
fn from(code: C, span: I) -> Self {
TokenizerError::new(code, span)
}
fn with_code(self, code: C) -> Self {
TokenizerError::with_code(self, code)
}
fn code(&self) -> Option<C> {
Some(self.code)
}
fn span(&self) -> Option<I> {
Some(self.span.clone())
}
fn err(&self) -> Option<&Self::WrappedError> {
Some(self)
}
fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
Some((self.code, self.span.clone(), self))
}
}
impl<C, I> From<TokenizerError<C, I>> for ParserError<C, I>
where
C: Code,
I: Clone,
{
fn from(value: TokenizerError<C, I>) -> Self {
ParserError::new(value.code, value.span)
}
}
impl<C, I> KParseError<C, I> for nom::Err<TokenizerError<C, I>>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
type WrappedError = TokenizerError<C, I>;
fn from(code: C, span: I) -> Self {
nom::Err::Error(KParseError::from(code, span))
}
fn code(&self) -> Option<C> {
match self {
nom::Err::Incomplete(_) => None,
nom::Err::Error(e) => Some(e.code),
nom::Err::Failure(e) => Some(e.code),
}
}
fn span(&self) -> Option<I> {
match self {
nom::Err::Incomplete(_) => None,
nom::Err::Error(e) => Some(e.span.clone()),
nom::Err::Failure(e) => Some(e.span.clone()),
}
}
fn err(&self) -> Option<&Self::WrappedError> {
match self {
nom::Err::Incomplete(_) => None,
nom::Err::Error(e) => Some(e),
nom::Err::Failure(e) => Some(e),
}
}
fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
match self {
nom::Err::Incomplete(_) => None,
nom::Err::Error(e) => Some((e.code, e.span.clone(), e)),
nom::Err::Failure(e) => Some((e.code, e.span.clone(), e)),
}
}
fn with_code(self, code: C) -> Self {
match self {
nom::Err::Incomplete(_) => self,
nom::Err::Error(e) => nom::Err::Error(e.with_code(code)),
nom::Err::Failure(e) => nom::Err::Failure(e.with_code(code)),
}
}
}
impl<C, I, O> KParseError<C, I> for Result<(I, O), nom::Err<TokenizerError<C, I>>>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
type WrappedError = TokenizerError<C, I>;
fn from(code: C, span: I) -> Self {
Err(nom::Err::Error(KParseError::from(code, span)))
}
fn code(&self) -> Option<C> {
match self {
Ok(_) => None,
Err(nom::Err::Error(e)) => Some(e.code),
Err(nom::Err::Failure(e)) => Some(e.code),
Err(nom::Err::Incomplete(_)) => None,
}
}
fn span(&self) -> Option<I> {
match self {
Ok(_) => None,
Err(nom::Err::Error(e)) => Some(e.span.clone()),
Err(nom::Err::Failure(e)) => Some(e.span.clone()),
Err(nom::Err::Incomplete(_)) => None,
}
}
fn err(&self) -> Option<&Self::WrappedError> {
match self {
Ok(_) => None,
Err(nom::Err::Error(e)) => Some(e),
Err(nom::Err::Failure(e)) => Some(e),
Err(nom::Err::Incomplete(_)) => None,
}
}
fn parts(&self) -> Option<(C, I, &Self::WrappedError)> {
match self {
Ok(_) => None,
Err(nom::Err::Error(e)) => Some((e.code, e.span.clone(), e)),
Err(nom::Err::Failure(e)) => Some((e.code, e.span.clone(), e)),
Err(nom::Err::Incomplete(_)) => None,
}
}
fn with_code(self, code: C) -> Self {
match self {
Ok((rest, token)) => Ok((rest, token)),
Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.with_code(code))),
Err(nom::Err::Failure(e)) => Err(nom::Err::Error(e.with_code(code))),
Err(nom::Err::Incomplete(e)) => Err(nom::Err::Incomplete(e)),
}
}
}
impl<C, I> nom::error::ParseError<I> for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug,
I: InputTake + InputLength + InputIter,
{
fn from_error_kind(input: I, _kind: ErrorKind) -> Self {
TokenizerError {
code: C::NOM_ERROR,
span: input,
}
}
fn append(_input: I, _kind: ErrorKind, other: Self) -> Self {
other
}
fn from_char(input: I, _char: char) -> Self {
TokenizerError {
code: C::NOM_ERROR,
span: input,
}
}
fn or(mut self, other: Self) -> Self {
self.append_err(other);
self
}
}
impl<C, I> Display for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.code)?;
write!(
f,
" for span {:?}",
restrict(DebugWidth::Short, self.span.clone()).fragment()
)?;
Ok(())
}
}
impl<C, I> Debug for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let dw: DebugWidth = f.width().into();
write!(f, "{}", self.code)?;
write!(
f,
" for span {:?}",
restrict(dw, self.span.clone()).fragment()
)?;
Ok(())
}
}
impl<C, I> Error for TokenizerError<C, I>
where
C: Code,
I: Clone + Debug + SpanFragment,
I: InputTake + InputLength + InputIter,
{
}
impl<C, I> TokenizerError<C, I>
where
C: Code,
I: Clone,
{
pub fn new(code: C, span: I) -> Self {
Self { code, span }
}
pub fn append_err(&mut self, other: TokenizerError<C, I>) {
if other.code != C::NOM_ERROR {
self.code = other.code;
self.span = other.span;
}
}
pub fn with_code(mut self, code: C) -> Self {
self.code = code;
self
}
pub fn error(self) -> nom::Err<Self> {
nom::Err::Error(self)
}
pub fn failure(self) -> nom::Err<Self> {
nom::Err::Failure(self)
}
}