]> git.lizzy.rs Git - rust.git/commitdiff
Rewrite reader::docs with an iterator.
authorMs2ger <ms2ger@gmail.com>
Sun, 17 May 2015 16:07:23 +0000 (18:07 +0200)
committerMs2ger <ms2ger@gmail.com>
Sun, 17 May 2015 20:28:04 +0000 (22:28 +0200)
src/librbml/lib.rs

index 23ce42626d948129b07ee4f52160f1722a262258..66fb579b1800fb2f0dde7b2c4f14fc0f35ae72ea 100644 (file)
@@ -400,17 +400,42 @@ pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> {
     pub fn docs<F>(d: Doc, mut it: F) -> bool where
         F: FnMut(usize, Doc) -> bool,
     {
-        let mut pos = d.start;
-        while pos < d.end {
-            let elt_tag = try_or!(tag_at(d.data, pos), false);
-            let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
-            pos = elt_size.next + elt_size.val;
-            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
-            if !it(elt_tag.val, doc) {
-                return false;
+        DocsIterator { d: d }.all(|(value, doc)| {
+            it(value, doc)
+        })
+    }
+
+    pub struct DocsIterator<'a> {
+        d: Doc<'a>,
+    }
+
+    impl<'a> Iterator for DocsIterator<'a> {
+        type Item = (usize, Doc<'a>);
+
+        fn next(&mut self) -> Option<(usize, Doc<'a>)> {
+            if self.d.start >= self.d.end {
+                return None;
             }
+
+            let elt_tag = try_or!(tag_at(self.d.data, self.d.start), {
+                self.d.start = self.d.end;
+                None
+            });
+            let elt_size = try_or!(tag_len_at(self.d.data, elt_tag), {
+                self.d.start = self.d.end;
+                None
+            });
+
+            let end = elt_size.next + elt_size.val;
+            let doc = Doc {
+                data: self.d.data,
+                start: elt_size.next,
+                end: end,
+            };
+
+            self.d.start = end;
+            return Some((elt_tag.val, doc));
         }
-        return true;
     }
 
     pub fn tagged_docs<F>(d: Doc, tg: usize, mut it: F) -> bool where