1use core::fmt;
6
7use crate::parser::Ev;
8use crate::{Error, Event, Parser};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum ReadError<E> {
13 Io(E),
15 Parse(Error),
17 BufferTooSmall,
20}
21
22impl<E> From<Error> for ReadError<E> {
23 fn from(e: Error) -> Self {
24 ReadError::Parse(e)
25 }
26}
27
28impl<E: fmt::Debug> fmt::Display for ReadError<E> {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 ReadError::Io(e) => write!(f, "read error: {e:?}"),
32 ReadError::Parse(e) => write!(f, "multipart error: {e}"),
33 ReadError::BufferTooSmall => f.write_str("buffer smaller than Parser::min_buffer()"),
34 }
35 }
36}
37
38impl<E: fmt::Debug> core::error::Error for ReadError<E> {}
39
40struct Core<'b, const BUF: usize, const LINE: usize, const MAX_HEADERS: usize> {
42 parser: Parser<'b, LINE, MAX_HEADERS>,
43 buf: [u8; BUF],
44 start: usize,
45 end: usize,
46 eof: bool,
47 pending: Option<(usize, Ev)>,
49}
50
51impl<'b, const BUF: usize, const LINE: usize, const MAX_HEADERS: usize>
52 Core<'b, BUF, LINE, MAX_HEADERS>
53{
54 fn new(parser: Parser<'b, LINE, MAX_HEADERS>) -> Self {
55 Core {
56 parser,
57 buf: [0; BUF],
58 start: 0,
59 end: 0,
60 eof: false,
61 pending: None,
62 }
63 }
64
65 fn advance(&mut self) -> Result<bool, Error> {
68 loop {
69 let input_at = self.start;
70 let input = self.buf.get(input_at..self.end).unwrap_or(&[]);
71 let (consumed, ev) = self.parser.step(input, self.eof)?;
72 self.start = self.start.saturating_add(consumed);
73 if let Some(ev) = ev {
74 self.pending = Some((input_at, ev));
75 return Ok(true);
76 }
77 if consumed == 0 {
78 return Ok(false);
79 }
80 }
81 }
82
83 fn event(&self) -> Event<'_, '_> {
85 let (at, ev) = self.pending.unwrap_or((0, Ev::Finished));
86 self.parser
87 .materialize(self.buf.get(at..self.end).unwrap_or(&[]), ev)
88 }
89
90 fn free<E>(&mut self) -> Result<&mut [u8], ReadError<E>> {
92 if self.start > 0 {
93 self.buf.copy_within(self.start..self.end, 0);
94 self.end = self.end.saturating_sub(self.start);
95 self.start = 0;
96 }
97 self.buf
100 .get_mut(self.end..)
101 .filter(|s| !s.is_empty())
102 .ok_or(ReadError::BufferTooSmall)
103 }
104
105 fn filled(&mut self, n: usize) {
106 if n == 0 {
107 self.eof = true;
108 } else {
109 self.end = self.end.saturating_add(n).min(BUF);
110 }
111 }
112}
113
114macro_rules! reader {
116 ($(#[$doc:meta])* $name:ident, $read:path $(, $async:ident $await:ident)?) => {
117 $(#[$doc])*
118 pub struct $name<'b, R, const BUF: usize, const LINE: usize = 512, const MAX_HEADERS: usize = 16> {
119 reader: R,
120 core: Core<'b, BUF, LINE, MAX_HEADERS>,
121 }
122
123 impl<'b, R: $read, const BUF: usize, const LINE: usize, const MAX_HEADERS: usize>
124 $name<'b, R, BUF, LINE, MAX_HEADERS>
125 {
126 pub fn new(reader: R, parser: Parser<'b, LINE, MAX_HEADERS>) -> Self {
128 $name { reader, core: Core::new(parser) }
129 }
130
131 pub $($async)? fn next_event(&mut self) -> Result<Event<'_, '_>, ReadError<R::Error>> {
137 while !self.core.advance()? {
138 let dst = self.core.free()?;
139 let n = self.reader.read(dst)$(.$await)?.map_err(ReadError::Io)?;
140 self.core.filled(n);
141 }
142 Ok(self.core.event())
143 }
144
145 pub fn parser(&self) -> &Parser<'b, LINE, MAX_HEADERS> {
147 &self.core.parser
148 }
149
150 pub fn into_inner(self) -> R {
152 self.reader
153 }
154 }
155 };
156}
157
158#[cfg(feature = "embedded-io")]
159reader!(
160 MultipartReader,
163 embedded_io::Read
164);
165
166#[cfg(feature = "embedded-io-async")]
167reader!(
168 MultipartReaderAsync,
171 embedded_io_async::Read,
172 async await
173);