use clap::ValueEnum;
use tabled::Tabled;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Author {
pub name: String,
pub email: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Trailer {
pub token: String,
pub value: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommitMeta {
pub author: Author,
pub time_seconds: i64,
pub trailers: Vec<Trailer>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct DiffStat {
pub insertions: u64,
pub deletions: u64,
pub files: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum SortBy {
Author,
Commits,
Files,
Insertions,
Deletions,
Net,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Options {
pub range: String,
pub email: bool,
pub reviews: bool,
pub sort: SortBy,
pub reverse: bool,
pub authors: Vec<String>,
pub since: Option<String>,
pub until: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Tabled)]
pub struct Stat {
#[tabled(rename = "Author")]
pub author: String,
#[tabled(rename = "Commits")]
pub commits: u64,
#[tabled(rename = "Changed Files")]
pub num_files: u64,
#[tabled(rename = "Insertions", display = "display_add")]
pub insertions: u64,
#[tabled(rename = "Deletions", display = "display_del")]
pub deletions: u64,
#[tabled(rename = "Net Δ", display = "display_net")]
pub net: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Tabled)]
pub struct Review {
#[tabled(rename = "Reviewer/Tester")]
pub author: String,
#[tabled(rename = "Commits")]
pub commits: u64,
}
#[must_use]
pub fn display_del(n: &u64) -> String {
match n {
0 => "0".to_string(),
n => format!("-{n}"),
}
}
#[must_use]
pub fn display_add(n: &u64) -> String {
match n {
0 => "0".to_string(),
n => format!("+{n}"),
}
}
#[must_use]
pub fn display_net(n: &i64) -> String {
if *n > 0 {
format!("+{n}")
} else {
format!("{n}")
}
}
#[cfg(test)]
mod tests {
use super::*;
use hegel::generators;
#[hegel::test]
fn display_add_signs_nonzero(tc: hegel::TestCase) {
let n = tc.draw(generators::integers::<u64>());
let rendered = display_add(&n);
if n == 0 {
assert_eq!(rendered, "0");
} else {
assert_eq!(rendered, format!("+{n}"));
}
}
#[hegel::test]
fn display_del_signs_nonzero(tc: hegel::TestCase) {
let n = tc.draw(generators::integers::<u64>());
let rendered = display_del(&n);
if n == 0 {
assert_eq!(rendered, "0");
} else {
assert_eq!(rendered, format!("-{n}"));
}
}
#[hegel::test]
fn display_net_signs_and_never_panics(tc: hegel::TestCase) {
let n = tc.draw(generators::integers::<i64>());
let rendered = display_net(&n);
if n > 0 {
assert_eq!(rendered, format!("+{n}"));
} else {
assert_eq!(rendered, n.to_string());
}
}
}