}
#[derive(Debug)]
+#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)]
#[allow(non_camel_case_types)]
pub enum PartName { m, d, Other }
Some(Component { name: part_name.unwrap_or(expected), payload_start: rhs })
}
+
+pub struct MetadataFieldIterator<'b> {
+ buf: &'b [u8],
+ last: Option<usize>,
+ iter: memchr::Memchr<'b>,
+}
+
+impl<'b> MetadataFieldIterator<'b> {
+ pub fn new(buf: &'b [u8]) -> Self { Self {
+ buf,
+ last: Some(0),
+ iter: memchr::Memchr::new(b'\n', buf),
+ } }
+
+ #[throws(AE)]
+ pub fn need<T>(&mut self) -> T
+ where T: FromStr,
+ T::Err: std::error::Error + Sync + Send + 'static,
+ {
+ self.parse()?.ok_or_else(|| anyhow!("missing"))?
+ }
+
+ #[throws(AE)]
+ pub fn parse<T>(&mut self) -> Option<T>
+ where T: FromStr,
+ T::Err: std::error::Error + Sync + Send + 'static,
+ {
+ let s = if let Some(r) = self.next() { r? } else { return None };
+ Some(s.parse()?)
+ }
+}
+
+impl<'b> Iterator for MetadataFieldIterator<'b> {
+ type Item = Result<&'b str, std::str::Utf8Error>;
+ fn next(&mut self) -> Option<Result<&'b str, std::str::Utf8Error>> {
+ let last = self.last?;
+ let (s, last) = match self.iter.next() {
+ Some(nl) => (&self.buf[last..nl], Some(nl+1)),
+ None => (&self.buf[last..], None),
+ };
+ self.last = last;
+ let s = str::from_utf8(s).map(|s| s.trim());
+ Some(s)
+ }
+}
+impl<'b> std::iter::FusedIterator for MetadataFieldIterator<'b> { }