pub struct Driver<B: AsMut<[u8]> + AsRef<[u8]>, S: Sink> { /* private fields */ }alloc only.Expand description
The one streaming implementation of the hook order: parser, inspector, sink, the text buffer, the sniff window, and the empty-file delay.
It takes its limits and policy from the parser. Because a PartHead
cannot outlive the parse call that produced it, the driver copies each
head once into an owned head and hands that copy to the delayed calls.
§Examples
use form_net::{Boundary, Driver, Limits, MemorySink, MultipartParser, NoInspector, Policy, Progress};
let parser = MultipartParser::new(Boundary::new(b"X")?, &Limits::DEFAULT, &Policy::DEFAULT)?;
let mut driver = Driver::new(parser, MemorySink::new());
let body = b"--X\r\nContent-Disposition: form-data; name=\"a\"\r\n\r\n1\r\n--X--";
let (consumed, progress) = driver.push(body, true, &mut NoInspector)?;
assert!(matches!(progress, Progress::Field { name: "a", value: b"1" }));
let (_, progress) = driver.push(&body[consumed..], true, &mut NoInspector)?;
assert!(matches!(progress, Progress::End));Implementations§
Source§impl<B: AsMut<[u8]> + AsRef<[u8]>, S: Sink> Driver<B, S>
impl<B: AsMut<[u8]> + AsRef<[u8]>, S: Sink> Driver<B, S>
Sourcepub fn new(parser: MultipartParser<B>, sink: S) -> Self
pub fn new(parser: MultipartParser<B>, sink: S) -> Self
A driver over parser writing files to sink.
§Examples
use form_net::{Boundary, DiscardSink, Driver, Limits, MultipartParser, Policy};
let parser = MultipartParser::new(Boundary::new(b"X")?, &Limits::DEFAULT, &Policy::DEFAULT)?;
let driver = Driver::new(parser, DiscardSink::default());
assert_eq!(driver.parser().bytes_seen(), 0);Sourcepub const fn parser(&self) -> &MultipartParser<B>
pub const fn parser(&self) -> &MultipartParser<B>
The parser.
§Examples
use form_net::{Boundary, Driver, Limits, MemorySink, MultipartParser, NoInspector, Policy};
let parser = MultipartParser::new(Boundary::new(b"X")?, &Limits::DEFAULT, &Policy::DEFAULT)?;
let mut driver = Driver::new(parser, MemorySink::new());
let body = b"--X\r\nContent-Disposition: form-data; name=a\r\n\r\n1\r\n--X--";
driver.push(body, true, &mut NoInspector)?;
assert_eq!(driver.parser().parts_seen(), 1);Sourcepub fn into_parts(self) -> (MultipartParser<B>, S)
pub fn into_parts(self) -> (MultipartParser<B>, S)
The parser and the sink.
§Examples
use form_net::{Boundary, DiscardSink, Driver, Limits, MultipartParser, Policy};
let parser = MultipartParser::new(Boundary::new(b"X")?, &Limits::DEFAULT, &Policy::DEFAULT)?;
let driver = Driver::new(parser, DiscardSink::default());
let (parser, _sink) = driver.into_parts();
assert!(!parser.is_done());Sourcepub fn push<'d, I: Inspector>(
&'d mut self,
input: &[u8],
eof: bool,
inspector: &mut I,
) -> Result<(usize, Progress<'d, S::Output>), FormError>
pub fn push<'d, I: Inspector>( &'d mut self, input: &[u8], eof: bool, inspector: &mut I, ) -> Result<(usize, Progress<'d, S::Output>), FormError>
Feeds input and returns how much was consumed and what completed: a
text field, a closed file (the sink’s output), a request for more
input, or the end. eof = true says input ends the body.
§Errors
Every multipart error, Refused, and the sink’s errors. On error the
sink has already been aborted and inspector.failed called; later
calls return Poisoned.
§Examples
use form_net::{Boundary, Driver, Limits, MemorySink, MultipartParser, NoInspector, Policy, Progress};
let parser = MultipartParser::new(Boundary::new(b"X")?, &Limits::DEFAULT, &Policy::DEFAULT)?;
let mut driver = Driver::new(parser, MemorySink::new());
let body = b"--X\r\nContent-Disposition: form-data; name=f; filename=a.txt\r\n\r\nhi\r\n--X--";
// The body arrives in two pieces; the first is not the end of it.
let (n, progress) = driver.push(&body[..20], false, &mut NoInspector)?;
assert_eq!((n, matches!(progress, Progress::NeedInput)), (20, true));
let (_, progress) = driver.push(&body[20..], true, &mut NoInspector)?;
assert!(matches!(progress, Progress::File(f) if f.bytes() == b"hi"));