use crate::*; pub enum EdnItem { Nil, Num(usize), Sym(T), Key(T), Exp(Vec>), } impl Default for EdnItem { fn default () -> Self { Self::Nil } } impl Debug for EdnItem { fn fmt (&self, f: &mut Formatter<'_>) -> Result<(), FormatError> { use EdnItem::*; match self { Nil => write!(f, "Nil"), Num(u) => write!(f, "Num({u})"), Sym(u) => write!(f, "Sym({u:?})"), Key(u) => write!(f, "Key({u:?})"), Exp(e) => write!(f, "Exp({})", itertools::join(e.iter().map(|i|format!("{:?}", i)), ",")) } } } impl PartialEq for EdnItem { fn eq (&self, other: &Self) -> bool { use EdnItem::*; match (self, other) { (Nil, Nil) => true, (Num(a), Num(b)) => a == b, (Sym(a), Sym(b)) => a == b, (Key(a), Key(b)) => a == b, (Exp(a), Exp(b)) => a == b, _ => false } } } impl + PartialEq + Default + Clone + std::fmt::Debug> EdnItem { pub fn to_ref (&self) -> EdnItem<&str> { match self { Self::Key(x) => EdnItem::Key(x.as_ref()), _ => todo!() } } pub fn to_str (&self) -> &str { match self { Self::Key(x) => x.as_ref(), _ => todo!() } } pub fn symbols <'a> (&'a self) -> EdnIterator<'a, T> { EdnIterator::new(&self) } } impl EdnItem { pub fn from (other: EdnItem>) -> EdnItem { use EdnItem::*; match other { Nil => Nil, Key(t) => Key(t.as_ref().to_string()), _ => todo!() } } } impl<'a> TryFrom> for EdnItem { type Error = ParseError; fn try_from (token: Token<'a>) -> Result { use Token::*; Ok(match token { Nil => Self::Nil, Num(chars, index, length) => Self::Num(Token::number(&chars[index..index+length])), Sym(chars, index, length) => Self::Sym(String::from(&chars[index..index+length])), Key(chars, index, length) => Self::Key(String::from(&chars[index..index+length])), Exp(chars, index, length, 0) => Self::Exp(Self::read_all(&chars[index+1..(index+length).saturating_sub(1)])?), _ => panic!("unclosed delimiter") }) } } impl<'a> TryFrom> for EdnItem<&'a str> { type Error = ParseError; fn try_from (token: Token<'a>) -> Result { use Token::*; Ok(match token { Nil => EdnItem::Nil, Num(chars, index, length) => Self::Num(Token::number(&chars[index..index+length])), Sym(chars, index, length) => Self::Sym(&chars[index..index+length]), Key(chars, index, length) => Self::Key(&chars[index..index+length]), Exp(chars, index, length, 0) => Self::Exp(Self::read_all(&chars[index+1..(index+length).saturating_sub(1)])?), _ => panic!("unclosed delimiter") }) } } impl<'a, T: std::fmt::Debug + Clone + Default + PartialEq + From<&'a str>> EdnItem { pub fn read_all (mut source: &'a str) -> Result, ParseError> { let mut items = vec![]; loop { if source.len() == 0 { break } let (remaining, token) = Token::chomp(source)?; match Self::read(token)? { Self::Nil => {}, item => items.push(item) }; source = remaining } Ok(items) } pub fn read_one (source: &'a str) -> Result<(Self, &'a str), ParseError> { Ok({ if source.len() == 0 { return Err(ParseError::Unknown(5)) } let (remaining, token) = Token::chomp(source)?; (Self::read(token)?, remaining) }) } pub fn read (token: Token<'a>) -> Result { use Token::*; Ok(match token { Nil => EdnItem::Nil, Num(chars, index, length) => Self::Num(Token::number(&chars[index..index+length])), Sym(chars, index, length) => Self::Sym(T::from(&chars[index..index+length])), Key(chars, index, length) => Self::Key(T::from(&chars[index..index+length])), Exp(chars, index, length, 0) => Self::Exp(Self::read_all(&chars[index+1..(index+length).saturating_sub(1)])?), _ => panic!("unclosed delimiter") }) } //pub fn to_str <'a> (&'a self) -> EdnItem<&'a str> { //use EdnItem::*; //match self { //Nil => Nil, //Num(n) => Num(*n), //Sym(t) => Sym(t.as_str()), //Key(t) => Key(t.as_str()), //Exp(t) => Exp(t.iter().map(|x|x.to_str()).collect()) //} //} }