Skip to main content

base_web_content/
content_event.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::UploadHead;
5use std::fmt;
6
7/// What one call to [`ContentParser::parse`](crate::ContentParser::parse) found, with the number of input bytes it consumed.
8#[derive(Clone, Debug, PartialEq, Eq)]
9#[non_exhaustive]
10pub struct ContentParsed<'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 for the caller.
14    pub event: ContentEvent<'a>,
15}
16
17/// One step through a body, for the caller to act on. It is exhaustive, so that a caller can match it without a wildcard; adding an event is a breaking change.
18///
19/// Fields other than uploads are buffered by the parser and reported only when parsing finishes. An accepted upload produces `Upload`, any number of `UploadContent`, and `UploadEnd`, after which the caller must give the parser a handle for what it stored with [`ContentParser::store`](crate::ContentParser::store) before parsing on. A body ends with `End`.
20#[derive(Clone, PartialEq, Eq)]
21pub enum ContentEvent<'a> {
22    /// An upload a declared field accepts begins. The caller should prepare storage for its content.
23    Upload(UploadHead),
24    /// Some of the current upload's content, borrowed from the input, for the caller to store. An upload's content may arrive in any number of pieces.
25    UploadContent(&'a [u8]),
26    /// The current upload's content is complete. The caller must give its handle with [`ContentParser::store`](crate::ContentParser::store).
27    UploadEnd,
28    /// The body is complete. Any input after it, a multipart body's epilogue, must still be given to later calls, which consume it within the epilogue limit and the body's maximum and report `End` again, or to [`ContentParser::parse_end`](crate::ContentParser::parse_end).
29    End,
30    /// The input ends before the next event: call again with more input, beginning with the bytes not yet consumed, or finish when the body has ended.
31    Incomplete,
32}
33
34/// Shows the length of content rather than its bytes, since an upload's content must not reach logs.
35impl fmt::Debug for ContentEvent<'_> {
36    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::Upload(head) => formatter.debug_tuple("Upload").field(head).finish(),
39            Self::UploadContent(content) => {
40                write!(formatter, "UploadContent(<{} bytes>)", content.len())
41            }
42            Self::UploadEnd => formatter.write_str("UploadEnd"),
43            Self::End => formatter.write_str("End"),
44            Self::Incomplete => formatter.write_str("Incomplete"),
45        }
46    }
47}