Skip to main content

base_web_multipart/
multipart_event.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::PartHead;
5use std::fmt;
6
7/// What one call to [`MultipartParser::parse`](crate::MultipartParser::parse) found, with the number of input bytes it consumed.
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9#[non_exhaustive]
10pub struct Parsed<'a> {
11    /// The input bytes consumed. The next call's input must begin with the bytes after them.
12    pub consumed: usize,
13    /// What the consumed bytes held.
14    pub event: MultipartEvent<'a>,
15}
16
17/// One step through a multipart body, borrowed from the parser's input.
18///
19/// A body produces, for each part, `Part`, any number of `Content`, then `PartEnd`, and finally `End`.
20#[derive(Clone, Copy, PartialEq, Eq)]
21pub enum MultipartEvent<'a> {
22    /// A part begins, with its header section.
23    Part(PartHead<'a>),
24    /// Some of the current part's content. A part's content may arrive in any number of pieces.
25    Content(&'a [u8]),
26    /// The current part's content is complete.
27    PartEnd,
28    /// The closing boundary was reached. Anything after it, the epilogue, is ignored.
29    End,
30    /// The input ends before the next event: call again with more input, beginning with the bytes not yet consumed.
31    Incomplete,
32}
33
34/// Shows the length of content rather than its bytes, since content such as a password field must not reach logs.
35impl fmt::Debug for MultipartEvent<'_> {
36    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::Part(head) => formatter.debug_tuple("Part").field(head).finish(),
39            Self::Content(content) => write!(formatter, "Content(<{} bytes>)", content.len()),
40            Self::PartEnd => formatter.write_str("PartEnd"),
41            Self::End => formatter.write_str("End"),
42            Self::Incomplete => formatter.write_str("Incomplete"),
43        }
44    }
45}