Skip to content

Commit 18f20d6

Browse files
committed
feat: add commit::ExtraHeaders::find_pos(), and expose "gpgsig" header name.
That way it it's easier to manipulate existing extra-header fields.
1 parent 5f0c124 commit 18f20d6

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

gix-object/src/commit/mod.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use winnow::prelude::*;
55

66
use crate::{Commit, CommitRef, TagRef};
77

8+
/// The well-known field name for gpg signatures.
9+
pub const SIGNATURE_FIELD_NAME: &'static str = "gpgsig";
10+
811
mod decode;
912
///
1013
pub mod message;
@@ -84,7 +87,7 @@ impl<'a> CommitRef<'a> {
8487
}
8588

8689
/// Returns a convenient iterator over all extra headers.
87-
pub fn extra_headers(&self) -> crate::commit::ExtraHeaders<impl Iterator<Item = (&BStr, &BStr)>> {
90+
pub fn extra_headers(&self) -> ExtraHeaders<impl Iterator<Item = (&BStr, &BStr)>> {
8891
ExtraHeaders::new(self.extra_headers.iter().map(|(k, v)| (*k, v.as_ref())))
8992
}
9093

@@ -147,16 +150,26 @@ where
147150
pub fn new(iter: I) -> Self {
148151
ExtraHeaders { inner: iter }
149152
}
153+
150154
/// Find the _value_ of the _first_ header with the given `name`.
151155
pub fn find(mut self, name: &str) -> Option<&'a BStr> {
152156
self.inner
153157
.find_map(move |(k, v)| if k == name.as_bytes().as_bstr() { Some(v) } else { None })
154158
}
159+
160+
/// Find the entry index with the given name, or return `None` if unavailable.
161+
pub fn find_pos(self, name: &str) -> Option<usize> {
162+
self.inner
163+
.enumerate()
164+
.find_map(|(pos, (field, _value))| (field == name).then_some(pos))
165+
}
166+
155167
/// Return an iterator over all _values_ of headers with the given `name`.
156168
pub fn find_all(self, name: &'a str) -> impl Iterator<Item = &'a BStr> {
157169
self.inner
158170
.filter_map(move |(k, v)| if k == name.as_bytes().as_bstr() { Some(v) } else { None })
159171
}
172+
160173
/// Return an iterator over all git mergetags.
161174
///
162175
/// A merge tag is a tag object embedded within the respective header field of a commit, making
@@ -167,6 +180,6 @@ where
167180

168181
/// Return the cryptographic signature provided by gpg/pgp verbatim.
169182
pub fn pgp_signature(self) -> Option<&'a BStr> {
170-
self.find("gpgsig")
183+
self.find(SIGNATURE_FIELD_NAME)
171184
}
172185
}

gix-object/tests/object/commit/from_bytes.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use gix_actor::SignatureRef;
2-
use gix_date::{time::Sign, Time};
3-
use gix_object::{bstr::ByteSlice, commit::message::body::TrailerRef, CommitRef};
4-
use smallvec::SmallVec;
5-
61
use crate::{
72
commit::{LONG_MESSAGE, MERGE_TAG, SIGNATURE},
83
fixture_name, linus_signature, signature,
94
};
5+
use gix_actor::SignatureRef;
6+
use gix_date::{time::Sign, Time};
7+
use gix_object::{bstr::ByteSlice, commit::message::body::TrailerRef, CommitRef};
8+
use smallvec::SmallVec;
109

1110
#[test]
1211
fn invalid_timestsamp() {
@@ -354,7 +353,12 @@ fn newline_right_after_signature_multiline_header() -> crate::Result {
354353
let pgp_sig = crate::commit::OTHER_SIGNATURE.as_bstr();
355354
assert_eq!(commit.extra_headers[0].1.as_ref(), pgp_sig);
356355
assert_eq!(commit.extra_headers().pgp_signature(), Some(pgp_sig));
357-
assert_eq!(commit.extra_headers().find("gpgsig"), Some(pgp_sig));
356+
assert_eq!(
357+
commit.extra_headers().find(gix_object::commit::SIGNATURE_FIELD_NAME),
358+
Some(pgp_sig)
359+
);
360+
assert_eq!(commit.extra_headers().find_pos("gpgsig"), Some(0));
361+
assert_eq!(commit.extra_headers().find_pos("something else"), None);
358362
assert!(commit.message.starts_with(b"Rollup"));
359363
Ok(())
360364
}

0 commit comments

Comments
 (0)