flexar 1.2.6

An extremely flexible lexer/parser (get it?) for writing your own programming language
Documentation
use std::{fmt::{Debug, Display}, ops::{Deref, DerefMut}};
use crate::cursor::Position;

/// A token generated by the lexer
#[derive(Debug, Clone)]
pub struct Token<TT: Display> {
    pub position: Position,
    pub token_type: TT,
}

/// A trait required to display a token nicely
pub trait TokenToString {
    fn to_string(&self) -> String;
}

impl<TT: Display> TokenToString for Option<&Token<TT>> {
    fn to_string(&self) -> String {
        self.map_or(" ".into(), |x| x.token_type.to_string())
    }
}

impl<TT: Debug + Display> Display for Token<TT> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.token_type)
    }
}

impl<TT: Display> Deref for Token<TT> {
    type Target = TT;
    fn deref(&self) -> &Self::Target {
        &self.token_type
    }
}

impl<TT: Display> DerefMut for Token<TT> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.token_type
    }
}

/// A node generated by the parser
#[derive(Clone)]
pub struct Node<N: Debug> {
    pub position: Position,
    pub node: N,
}

impl<N: Debug> Node<N> {
    pub fn new(position: Position, node: N) -> Self {
        Self {
            position,
            node,
        }
    }
}

impl<N: Debug> Deref for Node<N> {
    type Target = N;
    fn deref(&self) -> &Self::Target {
        &self.node
    }
}

impl<N: Debug> DerefMut for Node<N> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.node
    }
}

impl<N: Debug> Display for Node<N> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.node)
    }
}

impl<N: Debug> std::fmt::Debug for Node<N> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:#?} at {:?}", self.node, self.position)
    }
}