Skip to content

Commit 0d22ab4

Browse files
committed
feat: TagRefIter::tagger(). (#389)
Additionally ergonomics have been improved as the iterator is now `Copy`, similarly to the other iterators.
1 parent 6d023e3 commit 0d22ab4

File tree

4 files changed

+23
-9
lines changed

4 files changed

+23
-9
lines changed

git-object/src/commit/ref_iter.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ impl<'a> CommitRefIter<'a> {
7777
}
7878

7979
/// Returns the committer signature if there is no decoding error.
80-
/// Errors are coerced into options, hiding whether there was an error or not. The caller knows if there was an error or not.
8180
pub fn committer(mut self) -> Result<git_actor::SignatureRef<'a>, crate::decode::Error> {
8281
self.find_map(|t| match t {
8382
Ok(Token::Committer { signature }) => Some(Ok(signature)),
@@ -90,7 +89,6 @@ impl<'a> CommitRefIter<'a> {
9089
/// Returns the author signature if there is no decoding error.
9190
///
9291
/// It may contain white space surrounding it, and is exactly as parsed.
93-
/// Errors are coerced into options, hiding whether there was an error or not. The caller knows if there was an error or not.
9492
pub fn author(mut self) -> Result<git_actor::SignatureRef<'a>, crate::decode::Error> {
9593
self.find_map(|t| match t {
9694
Ok(Token::Author { signature }) => Some(Ok(signature)),
@@ -104,7 +102,6 @@ impl<'a> CommitRefIter<'a> {
104102
///
105103
/// It may contain white space surrounding it, and is exactly as
106104
// parsed.
107-
/// Errors are coerced into options, hiding whether there was an error or not. The caller knows if there was an error or not.
108105
pub fn message(mut self) -> Result<&'a BStr, crate::decode::Error> {
109106
self.find_map(|t| match t {
110107
Ok(Token::Message(msg)) => Some(Ok(msg)),

git-object/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ pub struct TagRef<'a> {
148148

149149
/// Like [`TagRef`], but as `Iterator` to support entirely allocation free parsing.
150150
/// It's particularly useful to dereference only the target chain.
151+
#[derive(Copy, Clone)]
151152
pub struct TagRefIter<'a> {
152153
data: &'a [u8],
153154
state: tag::ref_iter::State,

git-object/src/tag/ref_iter.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use nom::{
99

1010
use crate::{bstr::ByteSlice, parse, parse::NL, tag::decode, Kind, TagRefIter};
1111

12+
#[derive(Copy, Clone)]
1213
pub(crate) enum State {
1314
Target,
1415
TargetKind,
@@ -39,10 +40,21 @@ impl<'a> TagRefIter<'a> {
3940
/// Errors are coerced into options, hiding whether there was an error or not. The caller should assume an error if they
4041
/// call the method as intended. Such a squelched error cannot be recovered unless the objects data is retrieved and parsed again.
4142
/// `next()`.
42-
pub fn target_id(&mut self) -> Result<ObjectId, crate::decode::Error> {
43+
pub fn target_id(mut self) -> Result<ObjectId, crate::decode::Error> {
4344
let token = self.next().ok_or_else(missing_field)??;
4445
Token::into_id(token).ok_or_else(missing_field)
4546
}
47+
48+
/// Returns the taggers signature if there is no decoding error, and if this field exists.
49+
/// Errors are coerced into options, hiding whether there was an error or not. The caller knows if there was an error or not.
50+
pub fn tagger(mut self) -> Result<Option<git_actor::SignatureRef<'a>>, crate::decode::Error> {
51+
self.find_map(|t| match t {
52+
Ok(Token::Tagger(signature)) => Some(Ok(signature)),
53+
Err(err) => Some(Err(err)),
54+
_ => None,
55+
})
56+
.ok_or_else(missing_field)?
57+
}
4658
}
4759

4860
fn missing_field() -> crate::decode::Error {

git-object/tests/immutable/tag.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,21 @@ mod iter {
2626

2727
#[test]
2828
fn empty() -> crate::Result {
29+
let tag = fixture_bytes("tag", "empty.txt");
30+
let tag_iter = TagRefIter::from_bytes(&tag);
31+
let target_id = hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc");
32+
let tagger = Some(signature(1592381636));
2933
assert_eq!(
30-
TagRefIter::from_bytes(&fixture_bytes("tag", "empty.txt")).collect::<Result<Vec<_>, _>>()?,
34+
tag_iter.collect::<Result<Vec<_>, _>>()?,
3135
vec![
32-
Token::Target {
33-
id: hex_to_id("01dd4e2a978a9f5bd773dae6da7aa4a5ac1cdbbc")
34-
},
36+
Token::Target { id: target_id },
3537
Token::TargetKind(Kind::Commit),
3638
Token::Name(b"empty".as_bstr()),
37-
Token::Tagger(Some(signature(1592381636))),
39+
Token::Tagger(tagger),
3840
]
3941
);
42+
assert_eq!(tag_iter.target_id()?, target_id);
43+
assert_eq!(tag_iter.tagger()?, tagger);
4044
Ok(())
4145
}
4246

0 commit comments

Comments
 (0)