chiark / gitweb /
server: boundary_finder plumbing
[hippotat.git] / src / multipart.rs
index 112712bb8d5f4ad79d78f5e66473039b4357f46f..b858039c73e782c6993442548e70bf08c9f9be99 100644 (file)
@@ -15,6 +15,8 @@ pub struct Component<'b> {
 #[allow(non_camel_case_types)]
 pub enum PartName { m, d, Other }
 
+pub type BoundaryFinder = memchr::memmem::Finder<'static>;
+
 #[throws(AE)]
 pub fn process_component<'b>(warnings: &mut Warnings,
                              after_leader: &'b [u8], expected: PartName)
@@ -86,6 +88,37 @@ impl<'b> MetadataFieldIterator<'b> {
     last: Some(0),
     iter: memchr::Memchr::new(b'\n', buf),
   } }
+
+  #[throws(AE)]
+  pub fn need_next(&mut self) -> &'b str
+  {
+    self.next().ok_or_else(|| anyhow!("missing"))??
+  }
+
+  #[throws(AE)]
+  pub fn need_parse<T>(&mut self) -> T
+  where T: FromStr,
+        AE: From<T::Err>,
+  {
+    self.parse()?.ok_or_else(|| anyhow!("missing"))?
+  }
+
+  #[throws(AE)]
+  pub fn parse<T>(&mut self) -> Option<T>
+  where T: FromStr,
+        AE: From<T::Err>,
+  {
+    let s = if let Some(r) = self.next() { r? } else { return None };
+    Some(s.parse()?)
+  }
+
+  pub fn remaining_bytes_len(&self) -> usize {
+    if let Some(last) = self.last {
+      self.buf.len() - last
+    } else {
+      0
+    }
+  }
 }
                                       
 impl<'b> Iterator for MetadataFieldIterator<'b> {
@@ -101,3 +134,4 @@ impl<'b> Iterator for MetadataFieldIterator<'b> {
     Some(s)
   }
 }
+impl<'b> std::iter::FusedIterator for MetadataFieldIterator<'b> { }