use nu_ansi_term::{AnsiString as ANSIString, Style};
use crate::fs::fields as f;
use crate::output::cell::{DisplayWidth, TextCell};
impl f::Git {
pub fn render(self, colours: &dyn Colours) -> TextCell {
TextCell {
width: DisplayWidth::from(2),
contents: vec![self.staged.render(colours), self.unstaged.render(colours)].into(),
}
}
}
impl f::GitStatus {
fn render(self, colours: &dyn Colours) -> ANSIString<'static> {
#[rustfmt::skip]
return match self {
Self::NotModified => colours.not_modified().paint("-"),
Self::New => colours.new().paint("N"),
Self::Modified => colours.modified().paint("M"),
Self::Deleted => colours.deleted().paint("D"),
Self::Renamed => colours.renamed().paint("R"),
Self::TypeChange => colours.type_change().paint("T"),
Self::Ignored => colours.ignored().paint("I"),
Self::Conflicted => colours.conflicted().paint("U"),
};
}
}
pub trait Colours {
fn not_modified(&self) -> Style;
#[allow(clippy::new_ret_no_self, clippy::wrong_self_convention)]
fn new(&self) -> Style;
fn modified(&self) -> Style;
fn deleted(&self) -> Style;
fn renamed(&self) -> Style;
fn type_change(&self) -> Style;
fn ignored(&self) -> Style;
fn conflicted(&self) -> Style;
}
impl f::SubdirGitRepo {
pub fn render(self, colours: &dyn RepoColours) -> TextCell {
let branch_name = match self.branch {
Some(name) => {
if name == "main" || name == "master" {
colours.branch_main().paint(name)
} else {
colours.branch_other().paint(name)
}
}
None => colours.no_repo().paint("-"),
};
if let Some(status) = self.status {
TextCell {
width: DisplayWidth::from(2) + DisplayWidth::from(branch_name.as_str()),
contents: vec![
status.render(colours),
Style::default().paint(" "),
branch_name,
]
.into(),
}
} else {
TextCell {
width: DisplayWidth::from(branch_name.as_str()),
contents: vec![branch_name].into(),
}
}
}
}
impl f::SubdirGitRepoStatus {
pub fn render(self, colours: &dyn RepoColours) -> ANSIString<'static> {
match self {
Self::NoRepo => colours.no_repo().paint("-"),
Self::GitClean => colours.git_clean().paint("|"),
Self::GitDirty => colours.git_dirty().paint("+"),
}
}
}
pub trait RepoColours {
fn branch_main(&self) -> Style;
fn branch_other(&self) -> Style;
fn no_repo(&self) -> Style;
fn git_clean(&self) -> Style;
fn git_dirty(&self) -> Style;
}
#[cfg(test)]
pub mod test {
use super::Colours;
use crate::fs::fields as f;
use crate::output::cell::{DisplayWidth, TextCell};
use nu_ansi_term::Color::*;
use nu_ansi_term::Style;
struct TestColours;
impl Colours for TestColours {
fn not_modified(&self) -> Style {
Fixed(90).normal()
}
fn new(&self) -> Style {
Fixed(91).normal()
}
fn modified(&self) -> Style {
Fixed(92).normal()
}
fn deleted(&self) -> Style {
Fixed(93).normal()
}
fn renamed(&self) -> Style {
Fixed(94).normal()
}
fn type_change(&self) -> Style {
Fixed(95).normal()
}
fn ignored(&self) -> Style {
Fixed(96).normal()
}
fn conflicted(&self) -> Style {
Fixed(97).normal()
}
}
#[test]
fn git_blank() {
let stati = f::Git {
staged: f::GitStatus::NotModified,
unstaged: f::GitStatus::NotModified,
};
let expected = TextCell {
width: DisplayWidth::from(2),
contents: vec![Fixed(90).paint("-"), Fixed(90).paint("-")].into(),
};
assert_eq!(expected, stati.render(&TestColours));
}
#[test]
fn git_new_changed() {
let stati = f::Git {
staged: f::GitStatus::New,
unstaged: f::GitStatus::Modified,
};
let expected = TextCell {
width: DisplayWidth::from(2),
contents: vec![Fixed(91).paint("N"), Fixed(92).paint("M")].into(),
};
assert_eq!(expected, stati.render(&TestColours));
}
}