Sebastian Thielmake fmt (#301)50ff7aa4 years agoHistory
146 lines · 5.4 KB · Rust
RawDownload
use crate::{bstr::BStr, Commit, DetachedObject, Tree}; mod error {    use crate::object;     #[derive(Debug, thiserror::Error)]    #[allow(missing_docs)]    pub enum Error {        #[error(transparent)]        FindExistingObject(#[from] object::find::existing::OdbError),        #[error("The commit could not be decoded fully or partially")]        Decode(#[from] git_object::decode::Error),        #[error("Expected object of type {}, but got {}", .expected, .actual)]        ObjectKind {            expected: git_object::Kind,            actual: git_object::Kind,        },    }} pub use error::Error; use crate::id::Ancestors; impl<'repo> Commit<'repo> {    /// Create an owned instance of this object, copying our data in the process.    pub fn detached(&self) -> DetachedObject {        DetachedObject {            id: self.id,            kind: git_object::Kind::Commit,            data: self.data.clone(),        }    }     /// Sever the connection to the `Repository` and turn this instance into a standalone object.    pub fn detach(self) -> DetachedObject {        self.into()    }} impl<'repo> Commit<'repo> {    /// Turn this objects id into a shortened id with a length in hex as configured by `core.abbrev`.    pub fn short_id(&self) -> Result<git_hash::Prefix, crate::id::shorten::Error> {        use crate::ext::ObjectIdExt;        self.id.attach(self.repo).shorten()    }     /// Parse the commits message into a [`MessageRef`][git_object::commit::MessageRef]    pub fn message(&self) -> Result<git_object::commit::MessageRef<'_>, git_object::decode::Error> {        Ok(git_object::commit::MessageRef::from_bytes(self.message_raw()?))    }    /// Decode the entire commit object in full and return the raw message bytes.    pub fn message_raw(&self) -> Result<&'_ BStr, git_object::decode::Error> {        git_object::CommitRefIter::from_bytes(&self.data).message()    }    /// Decode the commit and obtain the time at which the commit was created.    ///    /// For the time at which it was authored, refer to `.decode()?.author.time`.    pub fn time(&self) -> Result<git_actor::Time, Error> {        Ok(self.committer()?.time)    }     /// Decode the entire commit object and return it for accessing all commit information.    ///    /// It will allocate only if there are more than 2 parents.    ///    /// Note that the returned commit object does make lookup easy and should be    /// used for successive calls to string-ish information to avoid decoding the object    /// more than once.    pub fn decode(&self) -> Result<git_object::CommitRef<'_>, git_object::decode::Error> {        git_object::CommitRef::from_bytes(&self.data)    }     /// Return an iterator over tokens, representing this commit piece by piece.    pub fn iter(&self) -> git_object::CommitRefIter<'_> {        git_object::CommitRefIter::from_bytes(&self.data)    }     /// Return the commits author, with surrounding whitespace trimmed.    pub fn author(&self) -> Result<git_actor::SignatureRef<'_>, git_object::decode::Error> {        git_object::CommitRefIter::from_bytes(&self.data)            .author()            .map(|s| s.trim())    }     /// Return the commits committer. with surrounding whitespace trimmed.    pub fn committer(&self) -> Result<git_actor::SignatureRef<'_>, git_object::decode::Error> {        git_object::CommitRefIter::from_bytes(&self.data)            .committer()            .map(|s| s.trim())    }     /// Decode this commits parent ids on the fly without allocating.    // TODO: tests    pub fn parent_ids(&self) -> impl Iterator<Item = crate::Id<'repo>> + '_ {        use crate::ext::ObjectIdExt;        let repo = self.repo;        git_object::CommitRefIter::from_bytes(&self.data)            .parent_ids()            .map(move |id| id.attach(repo))    }     /// Parse the commit and return the the tree object it points to.    pub fn tree(&self) -> Result<Tree<'repo>, Error> {        let tree_id = self.tree_id()?;        match self.repo.find_object(tree_id)?.try_into_tree() {            Ok(tree) => Ok(tree),            Err(crate::object::try_into::Error { actual, expected, .. }) => Err(Error::ObjectKind { actual, expected }),        }    }     /// Parse the commit and return the the tree id it points to.    pub fn tree_id(&self) -> Result<git_hash::ObjectId, git_object::decode::Error> {        git_object::CommitRefIter::from_bytes(&self.data).tree_id()    }     /// Return our id own id with connection to this repository.    pub fn id(&self) -> crate::Id<'repo> {        use crate::ext::ObjectIdExt;        self.id.attach(self.repo)    }     /// Obtain a platform for traversing ancestors of this commit.    pub fn ancestors(&self) -> Ancestors<'repo> {        self.id().ancestors()    }     /// Create a platform to further configure a `git describe` operation to find a name for this commit by looking    /// at the closest annotated tags (by default) in its past.    pub fn describe(&self) -> crate::commit::describe::Platform<'repo> {        crate::commit::describe::Platform {            id: self.id,            repo: self.repo,            select: Default::default(),            first_parent: false,            id_as_fallback: false,            max_candidates: 10,        }    }} impl<'r> std::fmt::Debug for Commit<'r> {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        write!(f, "Commit({})", self.id)    }}