History

[object #177] migrate immutable::commit into crate::commit

Sebastian Thiel committed 5 years ago

Commit 45d39341 parent 7f1955911 files · +75 −67Browse files

Showing the changes to git-object/src/commit/mod.rs (1 of 11 files). Show all

Unified · Split

git-object/src/commit/mod.rs+74−0
@@ -0,0 +1,74 @@
1use bstr::{BStr, ByteSlice};
2
3pub use ref_iter::RefIter;
4
5use crate::{immutable, TagRef};
6use crate::{immutable::object, CommitRef};
7
8mod decode;
9
10///
11pub mod ref_iter;
12
13impl<'a> CommitRef<'a> {
14 /// Deserialize a commit from the given `data` bytes while avoiding most allocations.
15 pub fn from_bytes(data: &'a [u8]) -> Result<CommitRef<'a>, object::decode::Error> {
16 decode::commit(data)
17 .map(|(_, t)| t)
18 .map_err(object::decode::Error::from)
19 }
20 /// Return the `tree` fields hash digest.
21 pub fn tree(&self) -> git_hash::ObjectId {
22 git_hash::ObjectId::from_hex(self.tree).expect("prior validation of tree hash during parsing")
23 }
24
25 /// Returns an iterator of parent object ids
26 pub fn parents(&self) -> impl Iterator<Item = git_hash::ObjectId> + '_ {
27 self.parents
28 .iter()
29 .map(|hex_hash| git_hash::ObjectId::from_hex(hex_hash).expect("prior validation of hashes during parsing"))
30 }
31
32 /// Returns a convenient iterator over all extra headers.
33 pub fn extra_headers(&self) -> crate::commit::ExtraHeaders<impl Iterator<Item = (&BStr, &BStr)>> {
34 crate::commit::ExtraHeaders::new(self.extra_headers.iter().map(|(k, v)| (*k, v.as_ref())))
35 }
36}
37
38/// An iterator over extra headers in [owned][crate::Commit] and [borrowed][crate::CommitRef] commits.
39pub struct ExtraHeaders<I> {
40 inner: I,
41}
42
43/// Instantiation and convenience.
44impl<'a, I> ExtraHeaders<I>
45where
46 I: Iterator<Item = (&'a BStr, &'a BStr)>,
47{
48 /// Create a new instance from an iterator over tuples of (name, value) pairs.
49 pub fn new(iter: I) -> Self {
50 ExtraHeaders { inner: iter }
51 }
52 /// Find the _value_ of the _first_ header with the given `name`.
53 pub fn find(mut self, name: &str) -> Option<&'a BStr> {
54 self.inner
55 .find_map(move |(k, v)| if k == name.as_bytes().as_bstr() { Some(v) } else { None })
56 }
57 /// Return an iterator over all _values_ of headers with the given `name`.
58 pub fn find_all(self, name: &'a str) -> impl Iterator<Item = &'a BStr> {
59 self.inner
60 .filter_map(move |(k, v)| if k == name.as_bytes().as_bstr() { Some(v) } else { None })
61 }
62 /// Return an iterator over all git mergetags.
63 ///
64 /// A merge tag is a tag object embedded within the respective header field of a commit, making
65 /// it a child object of sorts.
66 pub fn mergetags(self) -> impl Iterator<Item = Result<TagRef<'a>, immutable::object::decode::Error>> {
67 self.find_all("mergetag").map(|b| TagRef::from_bytes(b))
68 }
69
70 /// Return the cryptographic signature provided by gpg/pgp verbatim.
71 pub fn pgp_signature(self) -> Option<&'a BStr> {
72 self.find("gpgsig")
73 }
74}