1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::{CreateParserState, ParseResult, Parser};

/// A parser for a literal.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct LiteralParser<S: AsRef<str>> {
    literal: S,
}

impl<S: AsRef<str>> CreateParserState for LiteralParser<S> {
    fn create_parser_state(&self) -> <Self as Parser>::PartialState {
        LiteralParserOffset::default()
    }
}

impl<S: AsRef<str>> From<S> for LiteralParser<S> {
    fn from(literal: S) -> Self {
        Self { literal }
    }
}

impl<S: AsRef<str>> LiteralParser<S> {
    /// Create a new literal parser.
    pub fn new(literal: S) -> Self {
        Self { literal }
    }
}

/// The state of a literal parser.
#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
pub struct LiteralParserOffset {
    offset: usize,
}

impl LiteralParserOffset {
    /// Create a new literal parser state.
    pub fn new(offset: usize) -> Self {
        Self { offset }
    }
}

/// The error type for a literal parser.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct LiteralMismatchError;

impl std::fmt::Display for LiteralMismatchError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Literal mismatch")
    }
}

impl std::error::Error for LiteralMismatchError {}

impl<S: AsRef<str>> Parser for LiteralParser<S> {
    type Error = LiteralMismatchError;
    type Output = ();
    type PartialState = LiteralParserOffset;

    fn parse<'a>(
        &self,
        state: &LiteralParserOffset,
        input: &'a [u8],
    ) -> Result<ParseResult<'a, Self::PartialState, Self::Output>, Self::Error> {
        let mut bytes_consumed = 0;

        for (input_byte, literal_byte) in input
            .iter()
            .zip(self.literal.as_ref().as_bytes()[state.offset..].iter())
        {
            if input_byte != literal_byte {
                return Err(LiteralMismatchError);
            }
            bytes_consumed += 1;
        }

        if state.offset + bytes_consumed == self.literal.as_ref().len() {
            Ok(ParseResult::Finished {
                result: (),
                remaining: &input[bytes_consumed..],
            })
        } else {
            Ok(ParseResult::Incomplete {
                new_state: LiteralParserOffset {
                    offset: state.offset + bytes_consumed,
                },
                required_next: self
                    .literal
                    .as_ref()
                    .split_at(state.offset + bytes_consumed)
                    .1
                    .to_string()
                    .into(),
            })
        }
    }
}

#[test]
fn literal_parser() {
    let parser = LiteralParser {
        literal: "Hello, world!",
    };
    let state = LiteralParserOffset { offset: 0 };
    assert_eq!(
        parser.parse(&state, b"Hello, world!"),
        Ok(ParseResult::Finished {
            result: (),
            remaining: &[]
        })
    );
    assert_eq!(
        parser.parse(&state, b"Hello, "),
        Ok(ParseResult::Incomplete {
            new_state: LiteralParserOffset { offset: 7 },
            required_next: "world!".into()
        })
    );
    assert_eq!(
        parser.parse(
            &parser
                .parse(&state, b"Hello, ")
                .unwrap()
                .unwrap_incomplete()
                .0,
            b"world!"
        ),
        Ok(ParseResult::Finished {
            result: (),
            remaining: &[]
        })
    );
    assert_eq!(
        parser.parse(&state, b"Goodbye, world!"),
        Err(LiteralMismatchError)
    );
}