Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[derive(PartialEq, Eq)]
- pub enum Match<T, E> {
- Nothing,
- Next(T),
- Error(E),
- }
- pub trait ParseStream<T> {
- type Item;
- type Error;
- fn feed(&mut self, _: T) -> Match<Self::Item, Self::Error>;
- fn followed_by<P>(self, p: P) -> FollowedBy<Self, P>
- where Self: Sized, P: ParseStream<T, Error=Self::Error> {
- FollowedBy{ phase: FollowingPhase::A, pa: self, pb: p }
- }
- }
- enum FollowingPhase { A, B, Done }
- pub struct FollowedBy<A, B> {
- phase: FollowingPhase,
- pa: A,
- pb: B,
- }
- impl<A, B, T> ParseStream<T> for FollowedBy<A, B>
- where A: ParseStream<T>, B: ParseStream<T, Error=A::Error> {
- type Item = B::Item;
- type Error = B::Error;
- fn feed(&mut self, x: T) -> Match<Self::Item, Self::Error> {
- use FollowingPhase::*;
- match self.phase {
- A => {
- match self.pa.feed(x) {
- Match::Nothing => Match::Nothing,
- Match::Next(_) => {
- self.phase = B;
- Match::Nothing
- },
- Match::Error(e) => {
- self.phase = Done;
- Match::Error(e)
- }
- }
- },
- B => {
- match self.pb.feed(x) {
- Match::Nothing => Match::Nothing,
- Match::Next(y) => {
- self.phase = Done;
- Match::Next(y)
- },
- Match::Error(e) => {
- self.phase = Done;
- Match::Error(e)
- }
- }
- },
- Done => {
- Match::Nothing
- },
- }
- }
- }
- //----------------------------------------------------------------------
- pub struct LiteralByte(pub u8);
- impl ParseStream<u8> for LiteralByte {
- type Item = ();
- type Error = String;
- fn feed(&mut self, b: u8) -> Match<Self::Item, Self::Error> {
- if b == self.0 { Match::Next(()) }
- else { Match::Error("Not the right byte".to_string()) }
- }
- }
- pub struct AnyByte;
- impl ParseStream<u8> for AnyByte {
- type Item = u8;
- type Error = String;
- fn feed(&mut self, b: u8) -> Match<Self::Item, Self::Error> {
- Match::Next(b)
- }
- }
- fn main() {
- let mut p = LiteralByte(0xf5_u8).followed_by(AnyByte);
- assert!(p.feed(0xf5_u8) == Match::Nothing);
- assert!(p.feed(0x01_u8) == Match::Next(0x01_u8));
- assert!(p.feed(0x00_u8) == Match::Nothing);
- println!("hello");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement