Skip to content

Commit 8141765

Browse files
committed
feat: add TreeRefIter::offset_to_next_entry().
Add a function to help resume the iterator without holding onto the data directly.
1 parent e3c445e commit 8141765

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

gix-object/src/tree/ref_iter.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
use crate::{tree, tree::EntryRef, TreeRef, TreeRefIter};
12
use bstr::BStr;
23
use winnow::{error::ParserError, prelude::*};
34

4-
use crate::{tree, tree::EntryRef, TreeRef, TreeRefIter};
5-
65
impl<'a> TreeRefIter<'a> {
76
/// Instantiate an iterator from the given tree data.
87
pub fn from_bytes(data: &'a [u8]) -> TreeRefIter<'a> {
@@ -126,6 +125,21 @@ impl<'a> TreeRefIter<'a> {
126125
pub fn entries(self) -> Result<Vec<EntryRef<'a>>, crate::decode::Error> {
127126
self.collect()
128127
}
128+
129+
/// Return the offset in bytes that our data advanced from `buf`, the original buffer
130+
/// to the beginning of the data of the tree.
131+
///
132+
/// Then the tree-iteration can be resumed at the entry that would otherwise be returned next.
133+
pub fn offset_to_next_entry(&self, buf: &[u8]) -> usize {
134+
let before = (*buf).as_ptr();
135+
let after = (*self.data).as_ptr();
136+
137+
debug_assert!(
138+
before <= after,
139+
"`TreeRefIter::offset_to_next_entry(): {after:?} <= {before:?}) violated"
140+
);
141+
(after as usize - before as usize) / std::mem::size_of::<u8>()
142+
}
129143
}
130144

131145
impl<'a> Iterator for TreeRefIter<'a> {

gix-object/tests/object/tree/iter.rs

+18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ fn error_handling() {
2323
);
2424
}
2525

26+
#[test]
27+
fn offset_to_next_entry() {
28+
let buf = fixture_name("tree", "everything.tree");
29+
let mut iter = TreeRefIter::from_bytes(&buf);
30+
assert_eq!(iter.offset_to_next_entry(&buf), 0, "first entry is always at 0");
31+
iter.next();
32+
33+
let actual = iter.offset_to_next_entry(&buf);
34+
assert_eq!(actual, 31, "now the offset increases");
35+
assert_eq!(
36+
TreeRefIter::from_bytes(&buf[actual..])
37+
.next()
38+
.map(|e| e.unwrap().filename),
39+
iter.next().map(|e| e.unwrap().filename),
40+
"One can now start the iteration at a certain entry"
41+
);
42+
}
43+
2644
#[test]
2745
fn everything() -> crate::Result {
2846
assert_eq!(

0 commit comments

Comments
 (0)