use std::fmt;
use super::error::Result;
use super::id::Id;
use super::Repository;
mod delta;
mod deltas;
mod trailers;
pub use delta::Delta;
pub use deltas::Deltas;
pub use trailers::Trailers;
pub struct Commit<'a> {
repository: &'a Repository,
inner: git2::Commit<'a>,
}
impl Repository {
pub fn get<I>(&self, id: I) -> Result<Commit<'_>>
where
I: Into<Id>,
{
Ok(Commit {
repository: self,
inner: self.inner.find_commit(*id.into())?,
})
}
pub fn find<S>(&self, spec: S) -> Result<Commit<'_>>
where
S: AsRef<str>,
{
let object = self.inner.revparse_single(spec.as_ref())?;
Ok(Commit {
repository: self,
inner: object.peel_to_commit()?,
})
}
}
#[allow(clippy::must_use_candidate)]
impl Commit<'_> {
#[inline]
pub fn id(&self) -> Id {
self.inner.id().into()
}
#[allow(clippy::missing_panics_doc)]
#[inline]
pub fn summary(&self) -> &str {
self.inner.summary().expect("invariant")
}
#[inline]
pub fn body(&self) -> Option<&str> {
self.inner.body().filter(|body| !body.is_empty())
}
}
impl PartialEq for Commit<'_> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.inner.id() == other.inner.id()
}
}
impl Eq for Commit<'_> {}
impl fmt::Display for Commit<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.id().fmt(f)
}
}
impl fmt::Debug for Commit<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Commit")
.field("id", &self.id())
.field("summary", &self.summary())
.field("body", &self.body())
.finish()
}
}
pub fn trim_trailers(message: &str) -> Result<&str> {
let trailers: Trailers = message.parse()?;
if let Some((key, _)) = trailers.iter().next() {
Ok(message.split_once(key).map_or(message, |(body, _)| body))
} else {
Ok(message)
}
}