#![no_std]
extern crate no_std_compat as std;
use std::prelude::v1::*;
pub use git_testament_derive::{git_testament, git_testament_macros};
use std::fmt::{self, Display, Formatter};
#[derive(Debug)]
pub enum GitModification<'a> {
Added(&'a [u8]),
Removed(&'a [u8]),
Modified(&'a [u8]),
Untracked(&'a [u8]),
}
#[derive(Debug)]
pub enum CommitKind<'a> {
NoRepository(&'a str, &'a str),
NoCommit(&'a str, &'a str),
NoTags(&'a str, &'a str),
FromTag(&'a str, &'a str, &'a str, usize),
}
#[derive(Debug)]
pub struct GitTestament<'a> {
pub commit: CommitKind<'a>,
pub modifications: &'a [GitModification<'a>],
pub branch_name: Option<&'a str>,
}
pub const EMPTY_TESTAMENT: GitTestament = GitTestament {
commit: CommitKind::NoRepository("unknown", "unknown"),
modifications: &[],
branch_name: None,
};
#[cfg(feature = "alloc")]
impl<'a> GitTestament<'a> {
#[doc(hidden)]
pub fn _render_with_version(
&self,
pkg_version: &str,
trusted_branch: Option<&'static str>,
) -> String {
match self.commit {
CommitKind::FromTag(tag, hash, date, _) => {
let trusted = match trusted_branch {
Some(_) => {
if self.branch_name == trusted_branch {
self.modifications.is_empty()
} else {
false
}
}
None => false,
};
if trusted {
format!(
"{}",
GitTestament {
commit: CommitKind::FromTag(pkg_version, hash, date, 0),
..*self
}
)
} else if tag.contains(pkg_version) {
format!("{self}")
} else {
format!("{pkg_version} :: {self}")
}
}
_ => format!("{self}"),
}
}
}
#[cfg(feature = "alloc")]
#[macro_export]
macro_rules! render_testament {
( $testament:expr ) => {
$testament._render_with_version(env!("CARGO_PKG_VERSION"), None)
};
( $testament:expr, $trusted_branch:expr ) => {
$testament._render_with_version(env!("CARGO_PKG_VERSION"), Some($trusted_branch))
};
}
impl<'a> Display for CommitKind<'a> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
match self {
CommitKind::NoRepository(crate_ver, build_date) => {
write!(fmt, "{crate_ver} ({build_date})")
}
CommitKind::NoCommit(crate_ver, build_date) => {
write!(fmt, "{crate_ver} (uncommitted {build_date})")
}
CommitKind::NoTags(commit, when) => {
write!(fmt, "unknown ({} {})", &commit[..9], when)
}
CommitKind::FromTag(tag, commit, when, depth) => {
if *depth > 0 {
write!(fmt, "{}+{} ({} {})", tag, depth, &commit[..9], when)
} else {
write!(fmt, "{} ({} {})", tag, &commit[..9], when)
}
}
}
}
}
impl<'a> Display for GitTestament<'a> {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.commit.fmt(fmt)?;
if !self.modifications.is_empty() {
write!(
fmt,
" dirty {} modification{}",
self.modifications.len(),
if self.modifications.len() > 1 {
"s"
} else {
""
}
)?;
}
Ok(())
}
}