use std::{ fmt::Debug, ops::{Deref, DerefMut}, }; use super::{FileSpan, ParserError, ParserErrors, TokenCursor}; #[derive(Clone)] pub struct Node { pub inner: Result, pub span: FileSpan, } pub trait Parsable: Sized { fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Result; } pub trait MaybeParsable: Sized { fn maybe_parse( cursor: &mut TokenCursor, errors: &mut ParserErrors, ) -> Result, ParserError>; } impl Node { pub fn parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Self { let start = cursor.next_pos(); let inner = T::parse(cursor, errors).map_err(|e| errors.add(e)); let end = cursor.prev_end(); Self { inner, span: start.to(end), } } } impl Node { pub fn maybe_parse(cursor: &mut TokenCursor, errors: &mut ParserErrors) -> Option { let start = cursor.next_pos(); let inner = match T::maybe_parse(cursor, errors) { Ok(v) => Ok(v?), Err(e) => { errors.add(e); Err(()) } }; let end = cursor.prev_end(); Some(Self { inner, span: start.to(end), }) } } impl Node { pub fn new(inner: T, span: FileSpan) -> Self { Self { inner: Ok(inner), span, } } pub fn bx(self) -> Node> { Node { inner: self.inner.map(|v| Box::new(v)), span: self.span, } } } impl Node> { pub fn unbx(self) -> Node { Node { inner: self.inner.map(|v| *v), span: self.span, } } } impl Deref for Node { type Target = Result; fn deref(&self) -> &Self::Target { &self.inner } } impl DerefMut for Node { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } } impl Debug for Node { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.inner { Ok(v) => v.fmt(f), Err(_) => f.write_str("{error}"), } } }