combine/stream/
read.rs

1use std::{
2    fmt,
3    io::{self, Bytes, Read},
4};
5
6use crate::{
7    error::{ParseError, StreamError, Tracked},
8    stream::{StreamErrorFor, StreamOnce},
9};
10
11#[derive(Debug)]
12pub enum Error {
13    Unexpected,
14    EndOfInput,
15    Io(io::Error),
16}
17
18impl fmt::Display for Error {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match self {
21            Error::Unexpected => write!(f, "unexpected parse"),
22            Error::EndOfInput => write!(f, "unexpected end of input"),
23            Error::Io(err) => write!(f, "{}", err),
24        }
25    }
26}
27
28impl PartialEq for Error {
29    fn eq(&self, other: &Self) -> bool {
30        match (self, other) {
31            (Error::Unexpected, Error::Unexpected) => true,
32            (Error::EndOfInput, Error::EndOfInput) => true,
33            _ => false,
34        }
35    }
36}
37
38impl<Item, Range> StreamError<Item, Range> for Error {
39    #[inline]
40    fn unexpected_token(_: Item) -> Self {
41        Error::Unexpected
42    }
43    #[inline]
44    fn unexpected_range(_: Range) -> Self {
45        Error::Unexpected
46    }
47    #[inline]
48    fn unexpected_format<T>(_: T) -> Self
49    where
50        T: fmt::Display,
51    {
52        Error::Unexpected
53    }
54
55    #[inline]
56    fn expected_token(_: Item) -> Self {
57        Error::Unexpected
58    }
59    #[inline]
60    fn expected_range(_: Range) -> Self {
61        Error::Unexpected
62    }
63    #[inline]
64    fn expected_format<T>(_: T) -> Self
65    where
66        T: fmt::Display,
67    {
68        Error::Unexpected
69    }
70    #[inline]
71    fn message_format<T>(_: T) -> Self
72    where
73        T: fmt::Display,
74    {
75        Error::Unexpected
76    }
77    #[inline]
78    fn message_token(_: Item) -> Self {
79        Error::Unexpected
80    }
81    #[inline]
82    fn message_range(_: Range) -> Self {
83        Error::Unexpected
84    }
85
86    #[inline]
87    fn end_of_input() -> Self {
88        Error::EndOfInput
89    }
90
91    #[inline]
92    fn is_unexpected_end_of_input(&self) -> bool {
93        *self == Error::EndOfInput
94    }
95
96    #[inline]
97    fn into_other<T>(self) -> T
98    where
99        T: StreamError<Item, Range>,
100    {
101        match self {
102            Error::Unexpected => T::unexpected_static_message("parse"),
103            Error::EndOfInput => T::end_of_input(),
104            Error::Io(err) => T::other(err),
105        }
106    }
107}
108
109impl<Item, Range, Position> ParseError<Item, Range, Position> for Error
110where
111    Position: Default,
112{
113    type StreamError = Self;
114    #[inline]
115    fn empty(_position: Position) -> Self {
116        Error::Unexpected
117    }
118
119    #[inline]
120    fn from_error(_: Position, err: Self::StreamError) -> Self {
121        err
122    }
123
124    #[inline]
125    fn set_position(&mut self, _position: Position) {}
126
127    #[inline]
128    fn add(&mut self, err: Self::StreamError) {
129        *self = match (&*self, err) {
130            (Error::EndOfInput, _) => Error::EndOfInput,
131            (_, err) => err,
132        };
133    }
134
135    #[inline]
136    fn set_expected<F>(self_: &mut Tracked<Self>, info: Self::StreamError, f: F)
137    where
138        F: FnOnce(&mut Tracked<Self>),
139    {
140        f(self_);
141        self_.error = info;
142    }
143
144    fn is_unexpected_end_of_input(&self) -> bool {
145        *self == Error::EndOfInput
146    }
147
148    #[inline]
149    fn into_other<T>(self) -> T
150    where
151        T: ParseError<Item, Range, Position>,
152    {
153        T::from_error(Position::default(), StreamError::into_other(self))
154    }
155}
156
157pub struct Stream<R> {
158    bytes: Bytes<R>,
159}
160
161impl<R: Read> StreamOnce for Stream<R> {
162    type Token = u8;
163    type Range = &'static [u8];
164    type Position = usize;
165    type Error = Error;
166
167    #[inline]
168    fn uncons(&mut self) -> Result<u8, StreamErrorFor<Self>> {
169        match self.bytes.next() {
170            Some(Ok(b)) => Ok(b),
171            Some(Err(err)) => Err(Error::Io(err)),
172            None => Err(Error::EndOfInput),
173        }
174    }
175}
176
177impl<R> Stream<R>
178where
179    R: Read,
180{
181    /// Creates a `StreamOnce` instance from a value implementing `std::io::Read`.
182    ///
183    /// NOTE: This type do not implement `Positioned` and `Clone` and must be wrapped with types
184    ///     such as `BufferedStreamRef` and `State` to become a `Stream` which can be parsed
185    ///
186    /// ```rust
187    /// # #![cfg(feature = "std")]
188    /// # extern crate combine;
189    /// use combine::*;
190    /// use combine::parser::byte::*;
191    /// use combine::stream::read;
192    /// use combine::stream::buffered;
193    /// use combine::stream::position;
194    /// use std::io::Read;
195    ///
196    /// # fn main() {
197    /// let input: &[u8] = b"123,";
198    /// let stream = buffered::Stream::new(position::Stream::new(read::Stream::new(input)), 1);
199    /// let result = (many(digit()), byte(b','))
200    ///     .parse(stream)
201    ///     .map(|t| t.0);
202    /// assert_eq!(result, Ok((vec![b'1', b'2', b'3'], b',')));
203    /// # }
204    /// ```
205    pub fn new(read: R) -> Stream<R> {
206        Stream {
207            bytes: read.bytes(),
208        }
209    }
210}