use std::{fmt::{Debug, Display}, ops::{Deref, DerefMut}};
use crate::cursor::Position;
#[derive(Debug, Clone)]
pub struct Token<TT: Display> {
pub position: Position,
pub token_type: TT,
}
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
}
}
#[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)
}
}