use std::fmt;
use std::str::FromStr;
use crate::repository::commit::Commit;
use crate::repository::{Error, Result};
pub struct Trailers {
inner: git2::MessageTrailersStrs,
}
impl Commit<'_> {
#[allow(clippy::missing_panics_doc)]
#[inline]
pub fn trailers(&self) -> Result<Trailers> {
Trailers::from_str(self.inner.body().unwrap_or_default())
}
}
impl Trailers {
pub fn get<K>(&self, key: K) -> Option<&str>
where
K: AsRef<str>,
{
let mut iter = self.inner.iter();
iter.find_map(|(candidate, value)| {
(candidate == key.as_ref()).then_some(value)
})
}
pub fn contains_key<K>(&self, key: K) -> bool
where
K: AsRef<str>,
{
let mut iter = self.inner.iter();
iter.any(|(candidate, _)| candidate == key.as_ref())
}
#[inline]
#[must_use]
pub fn iter(&self) -> git2::MessageTrailersStrsIterator<'_> {
self.into_iter()
}
}
#[allow(clippy::must_use_candidate)]
impl Trailers {
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.inner.len() == 0
}
}
impl FromStr for Trailers {
type Err = Error;
fn from_str(value: &str) -> Result<Self> {
let prepared = format!("\n\n{value}");
Ok(Self {
inner: git2::message_trailers_strs(prepared.as_str())?,
})
}
}
impl<'a> IntoIterator for &'a Trailers {
type Item = (&'a str, &'a str);
type IntoIter = git2::MessageTrailersStrsIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.inner.iter()
}
}
impl fmt::Debug for Trailers {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_map().entries(self).finish()
}
}