use nu_ansi_term::Style;
use uzers::Users;
use crate::fs::fields as f;
use crate::output::cell::TextCell;
use crate::output::table::UserFormat;
pub trait Render {
fn render<C: Colours, U: Users>(self, colours: &C, users: &U, format: UserFormat) -> TextCell;
}
impl Render for Option<f::User> {
fn render<C: Colours, U: Users>(self, colours: &C, users: &U, format: UserFormat) -> TextCell {
#[rustfmt::skip]
let uid = match self {
Some(u) => u.0,
None => return TextCell::blank(colours.no_user()),
};
#[rustfmt::skip]
let user_name = match (format, users.get_user_by_uid(uid)) {
(_, None) => uid.to_string(),
(UserFormat::Numeric, _) => uid.to_string(),
(UserFormat::Name, Some(user)) => user.name().to_string_lossy().into(),
};
let style = if users.get_current_uid() == uid {
colours.you()
} else if uid == 0 {
colours.root()
} else {
colours.other()
};
TextCell::paint(style, user_name)
}
}
pub trait Colours {
fn you(&self) -> Style;
fn other(&self) -> Style;
fn root(&self) -> Style;
fn no_user(&self) -> Style;
}
#[cfg(test)]
#[allow(unused_results)]
pub mod test {
use super::{Colours, Render};
use crate::fs::fields as f;
use crate::output::cell::TextCell;
use crate::output::table::UserFormat;
use nu_ansi_term::Color::*;
use nu_ansi_term::Style;
use uzers::mock::MockUsers;
use uzers::User;
struct TestColours;
#[rustfmt::skip]
impl Colours for TestColours {
fn you(&self) -> Style { Red.bold() }
fn other(&self) -> Style { Blue.underline() }
fn root(&self) -> Style { Blue.underline() }
fn no_user(&self) -> Style { Black.italic() }
}
#[test]
fn named() {
let mut users = MockUsers::with_current_uid(1000);
users.add_user(User::new(1000, "enoch", 100));
let user = Some(f::User(1000));
let expected = TextCell::paint_str(Red.bold(), "enoch");
#[rustfmt::skip]
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Name));
let expected = TextCell::paint_str(Red.bold(), "1000");
#[rustfmt::skip]
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Numeric));
}
#[test]
fn unnamed() {
let users = MockUsers::with_current_uid(1000);
let user = Some(f::User(1000));
let expected = TextCell::paint_str(Red.bold(), "1000");
#[rustfmt::skip]
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Name));
#[rustfmt::skip]
assert_eq!(expected, user.render(&TestColours, &users, UserFormat::Numeric));
}
#[test]
fn different_named() {
let mut users = MockUsers::with_current_uid(0);
users.add_user(User::new(1000, "enoch", 100));
let user = Some(f::User(1000));
let expected = TextCell::paint_str(Blue.underline(), "enoch");
assert_eq!(
expected,
user.render(&TestColours, &users, UserFormat::Name)
);
}
#[test]
fn different_unnamed() {
let user = Some(f::User(1000));
let expected = TextCell::paint_str(Blue.underline(), "1000");
assert_eq!(
expected,
user.render(
&TestColours,
&MockUsers::with_current_uid(0),
UserFormat::Numeric
)
);
}
#[test]
fn overflow() {
let user = Some(f::User(2_147_483_648));
let expected = TextCell::paint_str(Blue.underline(), "2147483648");
assert_eq!(
expected,
user.render(
&TestColours,
&MockUsers::with_current_uid(0),
UserFormat::Numeric
)
);
}
}