Skip to content

Commit de9deef

Browse files
committed
Rewrite reader::docs with an iterator.
1 parent 8b7c17d commit de9deef

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

src/librbml/lib.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -400,17 +400,42 @@ pub mod reader {
400400
pub fn docs<F>(d: Doc, mut it: F) -> bool where
401401
F: FnMut(usize, Doc) -> bool,
402402
{
403-
let mut pos = d.start;
404-
while pos < d.end {
405-
let elt_tag = try_or!(tag_at(d.data, pos), false);
406-
let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
407-
pos = elt_size.next + elt_size.val;
408-
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
409-
if !it(elt_tag.val, doc) {
410-
return false;
403+
DocsIterator { d: d }.all(|(value, doc)| {
404+
it(value, doc)
405+
})
406+
}
407+
408+
pub struct DocsIterator<'a> {
409+
d: Doc<'a>,
410+
}
411+
412+
impl<'a> Iterator for DocsIterator<'a> {
413+
type Item = (usize, Doc<'a>);
414+
415+
fn next(&mut self) -> Option<(usize, Doc<'a>)> {
416+
if self.d.start >= self.d.end {
417+
return None;
411418
}
419+
420+
let elt_tag = try_or!(tag_at(self.d.data, self.d.start), {
421+
self.d.start = self.d.end;
422+
None
423+
});
424+
let elt_size = try_or!(tag_len_at(self.d.data, elt_tag), {
425+
self.d.start = self.d.end;
426+
None
427+
});
428+
429+
let end = elt_size.next + elt_size.val;
430+
let doc = Doc {
431+
data: self.d.data,
432+
start: elt_size.next,
433+
end: end,
434+
};
435+
436+
self.d.start = end;
437+
return Some((elt_tag.val, doc));
412438
}
413-
return true;
414439
}
415440

416441
pub fn tagged_docs<F>(d: Doc, tg: usize, mut it: F) -> bool where

0 commit comments

Comments
 (0)