use std::fmt; /// for internal use. /// parses only if the parser has no more bytes to yield. struct Eof; /// literal byte (character). pub struct Lit; /// parses without consuming any bytes from the parser. /// used to construct strictly optional constructs. pub struct Nul; /// the two-item sequence of A followed by B. pub struct Then(pub A, pub B); /// if A parses, then A, else parse B. pub enum Either { A(A), B(B), } /// parse A if possible, but don't error if it isn't present. pub type Maybe = Either; /// exists because Rust doesn't allow recursive type *aliases*. pub struct OneOrMore(Then< A, Maybe>> >); // case-sensitive u8 character. #[macro_export] macro_rules! lit { ($BYTE:literal) => { Lit<{ $BYTE as u8 }> } } // case-insensitive u8 character. #[macro_export] macro_rules! ilit { ($BYTE:literal) => { Either, Lit<{ ($BYTE as u8).to_ascii_uppercase() }>> } } pub type PResult = std::result::Result<(C, P), P>; pub trait Parser: Sized { fn expect_byte(self, b: Option) -> PResult; fn expect(self) -> PResult; // { // // support backtracking; i.e. don't modify `self` on failed parse // match C::consume(self.clone()) { // Ok(res) => res, // Err(_) => self, // } // } fn parse_all(self) -> Result { match self.expect::>() { Ok((Then(c, _eof), _p)) => Ok(c), Err(_p) => Err(()), } } } impl<'a> Parser for &'a [u8] { fn expect_byte(self, b: Option) -> PResult { match (b, self.split_first()) { // expected the correct character (Some(exp), Some((first, rest))) if *first == exp => Ok( ((), rest) ), // expected EOF, got EOF (None, None) => Ok( ((), self)), _ => Err(self), } } fn expect(self) -> PResult { match C::consume(self.clone()) { Ok(res) => Ok(res), // rewind the parser should we fail Err(_p) => Err(self), } } } pub trait Parse: Sized { fn consume(p: P) -> PResult; } impl Parse for Eof { fn consume(p: P) -> PResult { let (_, p) = p.expect_byte(None)?; Ok((Self, p)) } } impl Parse for Nul { fn consume(p: P) -> PResult { Ok((Self, p)) } } impl fmt::Display for Nul { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "") } } impl Parse for Lit { fn consume(p: P) -> PResult { let (_, p) = p.expect_byte(Some(BYTE))?; Ok((Self, p)) } } impl fmt::Display for Lit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", BYTE as char) } } impl Parse for Then { fn consume(p: P) -> PResult { let (a, p) = p.expect()?; let (b, p) = p.expect()?; Ok((Self(a, b), p)) } } impl fmt::Display for Then { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}{}", self.0, self.1) } } impl Parse for Either { fn consume(p: P) -> PResult { let p = match p.expect() { Ok((a, p)) => { return Ok((Self::A(a), p)); }, Err(p) => p, }; let p = match p.expect() { Ok((b, p)) => { return Ok((Self::B(b), p)); }, Err(p) => p, }; Err(p) } } impl fmt::Display for Either { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::A(a) => write!(f, "{}", a), Self::B(b) => write!(f, "{}", b), } } } impl Parse for Box { fn consume(p: P) -> PResult { match T::consume(p) { Ok((t, p)) => Ok((Box::new(t), p)), Err(p) => Err(p), } } } impl Parse for OneOrMore { fn consume(p: P) -> PResult { match p.expect() { Ok((t, p)) => Ok((Self(t), p)), Err(p) => Err(p), } } } impl fmt::Display for OneOrMore { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } }