exa/src/output/render/permissions.rs

198 lines
7.8 KiB
Rust
Raw Normal View History

2017-05-20 20:21:17 +00:00
use fs::fields as f;
use output::colours::Colours;
use output::cell::{TextCell, DisplayWidth};
2017-05-20 20:49:00 +00:00
use ansi_term::{ANSIString, Style};
2017-05-20 20:21:17 +00:00
impl f::PermissionsPlus {
pub fn render(&self, colours: &Colours) -> TextCell {
let mut chars = vec![ self.file_type.render(colours) ];
chars.extend(self.permissions.render(colours, self.file_type.is_regular_file()));
if self.xattrs {
2017-05-20 20:21:17 +00:00
chars.push(colours.perms.attribute.paint("@"));
}
// As these are all ASCII characters, we can guarantee that theyre
// all going to be one character wide, and dont need to compute the
// cells display width.
TextCell {
2017-05-21 09:51:42 +00:00
width: DisplayWidth::from(chars.len()),
contents: chars.into(),
}
}
}
impl f::Permissions {
pub fn render(&self, colours: &Colours, is_regular_file: bool) -> Vec<ANSIString<'static>> {
let bit = |bit, chr: &'static str, style: Style| {
if bit { style.paint(chr) } else { colours.punctuation.paint("-") }
};
vec![
bit(self.user_read, "r", colours.perms.user_read),
bit(self.user_write, "w", colours.perms.user_write),
self.user_execute_bit(colours, is_regular_file),
bit(self.group_read, "r", colours.perms.group_read),
bit(self.group_write, "w", colours.perms.group_write),
self.group_execute_bit(colours),
bit(self.other_read, "r", colours.perms.other_read),
bit(self.other_write, "w", colours.perms.other_write),
self.other_execute_bit(colours)
]
}
fn user_execute_bit(&self, colours: &Colours, is_regular_file: bool) -> ANSIString<'static> {
match (self.user_execute, self.setuid, is_regular_file) {
(false, false, _) => colours.punctuation.paint("-"),
(true, false, false) => colours.perms.user_execute_other.paint("x"),
(true, false, true) => colours.perms.user_execute_file.paint("x"),
(false, true, _) => colours.perms.special_other.paint("S"),
(true, true, false) => colours.perms.special_other.paint("s"),
(true, true, true) => colours.perms.special_user_file.paint("s"),
}
}
fn group_execute_bit(&self, colours: &Colours) -> ANSIString<'static> {
match (self.group_execute, self.setgid) {
(false, false) => colours.punctuation.paint("-"),
(true, false) => colours.perms.group_execute.paint("x"),
(false, true) => colours.perms.special_other.paint("S"),
(true, true) => colours.perms.special_other.paint("s"),
}
}
fn other_execute_bit(&self, colours: &Colours) -> ANSIString<'static> {
match (self.other_execute, self.sticky) {
(false, false) => colours.punctuation.paint("-"),
(true, false) => colours.perms.other_execute.paint("x"),
(false, true) => colours.perms.special_other.paint("T"),
(true, true) => colours.perms.special_other.paint("t"),
}
}
2017-05-20 20:21:17 +00:00
}
2017-05-20 20:49:00 +00:00
impl f::Type {
pub fn render(&self, colours: &Colours) -> ANSIString<'static> {
match *self {
f::Type::File => colours.filetypes.normal.paint("."),
f::Type::Directory => colours.filetypes.directory.paint("d"),
f::Type::Pipe => colours.filetypes.pipe.paint("|"),
f::Type::Link => colours.filetypes.symlink.paint("l"),
f::Type::CharDevice => colours.filetypes.device.paint("c"),
f::Type::BlockDevice => colours.filetypes.device.paint("b"),
f::Type::Socket => colours.filetypes.socket.paint("s"),
f::Type::Special => colours.filetypes.special.paint("?"),
}
}
}
2017-05-20 20:21:17 +00:00
#[cfg(test)]
#[allow(unused_results)]
pub mod test {
use output::colours::Colours;
use output::cell::TextCellContents;
2017-05-20 20:21:17 +00:00
use fs::fields as f;
use ansi_term::Colour::*;
#[test]
fn negate() {
let mut colours = Colours::default();
colours.punctuation = Fixed(11).normal();
2017-05-20 20:21:17 +00:00
let bits = f::Permissions {
user_read: false, user_write: false, user_execute: false, setuid: false,
group_read: false, group_write: false, group_execute: false, setgid: false,
other_read: false, other_write: false, other_execute: false, sticky: false,
};
2017-05-20 20:21:17 +00:00
let expected = TextCellContents::from(vec![
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(11).paint("-"),
]);
2017-05-20 20:21:17 +00:00
assert_eq!(expected, bits.render(&colours, false).into())
2017-05-20 20:21:17 +00:00
}
#[test]
fn affirm() {
let mut colours = Colours::default();
colours.perms.user_read = Fixed(101).normal();
colours.perms.user_write = Fixed(102).normal();
colours.perms.user_execute_file = Fixed(103).normal();
colours.perms.group_read = Fixed(104).normal();
colours.perms.group_write = Fixed(105).normal();
colours.perms.group_execute = Fixed(106).normal();
colours.perms.other_read = Fixed(107).normal();
colours.perms.other_write = Fixed(108).normal();
colours.perms.other_execute = Fixed(109).normal();
let bits = f::Permissions {
user_read: true, user_write: true, user_execute: true, setuid: false,
group_read: true, group_write: true, group_execute: true, setgid: false,
other_read: true, other_write: true, other_execute: true, sticky: false,
};
let expected = TextCellContents::from(vec![
Fixed(101).paint("r"), Fixed(102).paint("w"), Fixed(103).paint("x"),
Fixed(104).paint("r"), Fixed(105).paint("w"), Fixed(106).paint("x"),
Fixed(107).paint("r"), Fixed(108).paint("w"), Fixed(109).paint("x"),
]);
assert_eq!(expected, bits.render(&colours, true).into())
}
#[test]
fn specials() {
let mut colours = Colours::default();
colours.punctuation = Fixed(11).normal();
colours.perms.special_user_file = Fixed(77).normal();
colours.perms.special_other = Fixed(88).normal();
let bits = f::Permissions {
user_read: false, user_write: false, user_execute: true, setuid: true,
group_read: false, group_write: false, group_execute: true, setgid: true,
other_read: false, other_write: false, other_execute: true, sticky: true,
};
let expected = TextCellContents::from(vec![
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(77).paint("s"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("s"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("t"),
]);
assert_eq!(expected, bits.render(&colours, true).into())
}
#[test]
fn extra_specials() {
let mut colours = Colours::default();
colours.punctuation = Fixed(11).normal();
colours.perms.special_other = Fixed(88).normal();
let bits = f::Permissions {
user_read: false, user_write: false, user_execute: false, setuid: true,
group_read: false, group_write: false, group_execute: false, setgid: true,
other_read: false, other_write: false, other_execute: false, sticky: true,
};
let expected = TextCellContents::from(vec![
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("S"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("S"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(88).paint("T"),
]);
assert_eq!(expected, bits.render(&colours, true).into())
2017-05-20 20:21:17 +00:00
}
}