pub struct UrlencodedParser<B: AsMut<[u8]> + AsRef<[u8]>> { /* private fields */ }Expand description
A streaming urlencoded parser over a caller scratch buffer.
A sequence that ends inside the current chunk is returned borrowed from
the input; one that straddles chunks is assembled in the scratch buffer
(Limits::urlencoded_buffer_len bytes) and returned borrowed from it.
A sequence too long for its budgets is refused as soon as its first
bytes prove it, before it is copied, so the scratch never overflows.
Pairs and errors are the same for every split of the same body.
§Examples
use form_net::{Limits, UrlencodedEvent, UrlencodedParser};
// A small route: the scratch fits on the stack.
const LIMITS: Limits = Limits::DEFAULT.with_max_name_bytes(32).with_max_value_bytes(256);
let mut scratch = [0u8; LIMITS.urlencoded_buffer_len()];
let mut parser = UrlencodedParser::with_buffer(&LIMITS, &mut scratch[..])?;
let mut names = Vec::new();
for (chunk, last) in [(&b"na"[..], false), (b"me=Al&ci", false), (b"ty=Paris", true)] {
let mut rest = chunk;
loop {
let step = parser.parse(rest, last)?;
rest = &rest[step.consumed..];
match step.event {
UrlencodedEvent::Pair(p) => names.push(p.name_raw().to_vec()),
_ => break,
}
}
}
assert_eq!(names, [b"name".to_vec(), b"city".to_vec()]);Implementations§
Source§impl<B: AsMut<[u8]> + AsRef<[u8]>> UrlencodedParser<B>
impl<B: AsMut<[u8]> + AsRef<[u8]>> UrlencodedParser<B>
Sourcepub fn with_buffer(limits: &Limits, scratch: B) -> Result<Self, FormError>
pub fn with_buffer(limits: &Limits, scratch: B) -> Result<Self, FormError>
A parser over scratch, which must hold at least
Limits::urlencoded_buffer_len bytes.
§Errors
InvalidLimits; BufferTooSmall { needed }.
§Examples
use form_net::{FormError, Limits, UrlencodedParser};
let needed = Limits::DEFAULT.urlencoded_buffer_len();
let mut small = [0u8; 16];
let err = UrlencodedParser::with_buffer(&Limits::DEFAULT, &mut small[..]).unwrap_err();
assert_eq!(err, FormError::BufferTooSmall { needed });
let parser = UrlencodedParser::with_buffer(&Limits::DEFAULT, vec![0u8; needed])?;
assert_eq!(parser.bytes_seen(), 0);Sourcepub fn parse<'p>(
&'p mut self,
input: &'p [u8],
eof: bool,
) -> Result<UrlencodedStep<'p>, FormError>
pub fn parse<'p>( &'p mut self, input: &'p [u8], eof: bool, ) -> Result<UrlencodedStep<'p>, FormError>
Feeds input (eof = true says it ends the body) and returns the
next pair, a request for more input, or the end.
§Errors
The errors of raw_pairs; Poisoned after an
error until reset.
§Examples
use form_net::{Limits, UrlencodedEvent, UrlencodedParser};
let mut body = &b"q=rust&page=2"[..];
let mut names = Vec::new();
loop {
let step = parser.parse(body, true)?;
body = &body[step.consumed..];
match step.event {
UrlencodedEvent::Pair(p) => names.push(p.name_raw().to_vec()),
_ => break,
}
}
assert_eq!(names, [b"q".to_vec(), b"page".to_vec()]);Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Clears the counters and the poisoned state and wipes the scratch, for the next body.
§Examples
use form_net::{FormError, Limits, UrlencodedEvent, UrlencodedParser};
let limits = Limits::DEFAULT.with_max_name_bytes(4);
let mut parser = UrlencodedParser::with_buffer(&limits, vec![0u8; limits.urlencoded_buffer_len()])?;
assert!(parser.parse(b"too_long=1", true).is_err());
assert_eq!(parser.parse(b"a=1", true).unwrap_err(), FormError::Poisoned);
parser.reset();
assert!(matches!(parser.parse(b"a=1", true)?.event, UrlencodedEvent::Pair(_)));Sourcepub const fn bytes_seen(&self) -> u64
pub const fn bytes_seen(&self) -> u64
Body bytes consumed so far.
§Examples
use form_net::{Limits, UrlencodedParser};
let consumed = parser.parse(b"a=1&b=2", false)?.consumed;
assert_eq!((consumed, parser.bytes_seen()), (4, 4));Source§impl UrlencodedParser<Vec<u8>>
impl UrlencodedParser<Vec<u8>>
Sourcepub fn new(limits: &Limits) -> Result<Self, FormError>
Available on crate feature alloc only.
pub fn new(limits: &Limits) -> Result<Self, FormError>
alloc only.A parser that owns its scratch buffer.
§Errors
InvalidLimits.
§Examples
use form_net::{Limits, UrlencodedEvent, UrlencodedParser};
let mut parser = UrlencodedParser::new(&Limits::DEFAULT)?;
let step = parser.parse(b"a=1", true)?;
assert!(matches!(step.event, UrlencodedEvent::Pair(p) if p.value_raw() == b"1"));