Skip to content

Commit 91065cd

Browse files
committed
feat: CommitRefIter::parent_ids() (#364)
Allocation-free parent retrieval.
1 parent 9c8e449 commit 91065cd

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

git-object/src/commit/ref_iter.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub(crate) enum SignatureKind {
1717
Committer,
1818
}
1919

20+
#[derive(Copy, Clone)]
2021
pub(crate) enum State {
2122
Tree,
2223
Parents,
@@ -52,12 +53,22 @@ impl<'a> CommitRefIter<'a> {
5253
self.next().and_then(Result::ok).and_then(Token::try_into_id)
5354
}
5455

56+
/// Return all parent_ids as iterator.
57+
///
58+
/// Parsing errors are ignored quietly.
59+
pub fn parent_ids(self) -> impl Iterator<Item = git_hash::ObjectId> + 'a {
60+
self.filter_map(|t| match t {
61+
Ok(Token::Parent { id }) => Some(id),
62+
_ => None,
63+
})
64+
}
65+
5566
/// Returns all signatures, first the author, then the committer, if there is no decoding error.
5667
///
5768
/// Errors are coerced into options, hiding whether there was an error or not. The caller knows if there was an error or not
5869
/// if not exactly two signatures were iterable.
5970
/// Errors are not the common case - if an error needs to be detectable, use this instance as iterator.
60-
pub fn signatures(&'a mut self) -> impl Iterator<Item = git_actor::SignatureRef<'_>> + 'a {
71+
pub fn signatures(self) -> impl Iterator<Item = git_actor::SignatureRef<'a>> + 'a {
6172
self.filter_map(|t| match t {
6273
Ok(Token::Author { signature }) | Ok(Token::Committer { signature }) => Some(signature),
6374
_ => None,

git-object/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub struct CommitRef<'a> {
9393

9494
/// Like [`CommitRef`][crate::CommitRef], but as `Iterator` to support (up to) entirely allocation free parsing.
9595
/// It's particularly useful to traverse the commit graph without ever allocating arrays for parents.
96+
#[derive(Copy, Clone)]
9697
pub struct CommitRefIter<'a> {
9798
data: &'a [u8],
9899
state: commit::ref_iter::State,
@@ -212,10 +213,8 @@ pub struct TreeRef<'a> {
212213

213214
/// A directory snapshot containing files (blobs), directories (trees) and submodules (commits), lazily evaluated.
214215
#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
215-
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
216216
pub struct TreeRefIter<'a> {
217217
/// The directories and files contained in this tree.
218-
#[cfg_attr(feature = "serde1", serde(borrow))]
219218
data: &'a [u8],
220219
}
221220

git-object/tests/immutable/commit/iter.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ fn signed_singleline() -> crate::Result {
112112
Token::Message(b"update tasks\n".as_bstr()),
113113
]
114114
);
115+
assert_eq!(
116+
CommitRefIter::from_bytes(&fixture_bytes("commit", "signed-singleline.txt"))
117+
.parent_ids()
118+
.collect::<Vec<_>>(),
119+
vec![hex_to_id("09d8d3a12e161a7f6afb522dbe8900a9c09bce06")]
120+
);
115121
Ok(())
116122
}
117123

@@ -151,6 +157,15 @@ fn mergetag() -> crate::Result {
151157
Token::Message(LONG_MESSAGE.as_bytes().as_bstr()),
152158
]
153159
);
160+
assert_eq!(
161+
CommitRefIter::from_bytes(&fixture_bytes("commit", "mergetag.txt"))
162+
.parent_ids()
163+
.collect::<Vec<_>>(),
164+
vec![
165+
hex_to_id("44ebe016df3aad96e3be8f95ec52397728dd7701"),
166+
hex_to_id("8d485da0ddee79d0e6713405694253d401e41b93")
167+
]
168+
);
154169
Ok(())
155170
}
156171

@@ -174,6 +189,12 @@ mod method {
174189
.collect::<Vec<_>>(),
175190
vec![signature(1592437401), signature(1592437401)]
176191
);
192+
assert_eq!(
193+
CommitRefIter::from_bytes(&fixture_bytes("commit", "unsigned.txt"))
194+
.parent_ids()
195+
.count(),
196+
0
197+
);
177198
Ok(())
178199
}
179200

0 commit comments

Comments
 (0)