exa/src/output/render/permissions.rs

205 lines
7.7 KiB
Rust
Raw Normal View History

use ansi_term::{ANSIString, Style};
2018-12-07 23:43:31 +00:00
use crate::fs::fields as f;
use crate::output::cell::{TextCell, DisplayWidth};
use crate::output::render::FiletypeColours;
2017-05-20 20:21:17 +00:00
impl f::PermissionsPlus {
pub fn render<C: Colours+FiletypeColours>(&self, colours: &C) -> 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 {
chars.push(colours.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<C: Colours>(&self, colours: &C, is_regular_file: bool) -> Vec<ANSIString<'static>> {
let bit = |bit, chr: &'static str, style: Style| {
if bit { style.paint(chr) }
else { colours.dash().paint("-") }
};
vec![
bit(self.user_read, "r", colours.user_read()),
bit(self.user_write, "w", colours.user_write()),
self.user_execute_bit(colours, is_regular_file),
bit(self.group_read, "r", colours.group_read()),
bit(self.group_write, "w", colours.group_write()),
self.group_execute_bit(colours),
bit(self.other_read, "r", colours.other_read()),
bit(self.other_write, "w", colours.other_write()),
self.other_execute_bit(colours)
]
}
fn user_execute_bit<C: Colours>(&self, colours: &C, is_regular_file: bool) -> ANSIString<'static> {
match (self.user_execute, self.setuid, is_regular_file) {
(false, false, _) => colours.dash().paint("-"),
(true, false, false) => colours.user_execute_other().paint("x"),
(true, false, true) => colours.user_execute_file().paint("x"),
(false, true, _) => colours.special_other().paint("S"),
(true, true, false) => colours.special_other().paint("s"),
(true, true, true) => colours.special_user_file().paint("s"),
}
}
fn group_execute_bit<C: Colours>(&self, colours: &C) -> ANSIString<'static> {
match (self.group_execute, self.setgid) {
(false, false) => colours.dash().paint("-"),
(true, false) => colours.group_execute().paint("x"),
(false, true) => colours.special_other().paint("S"),
(true, true) => colours.special_other().paint("s"),
}
}
fn other_execute_bit<C: Colours>(&self, colours: &C) -> ANSIString<'static> {
match (self.other_execute, self.sticky) {
(false, false) => colours.dash().paint("-"),
(true, false) => colours.other_execute().paint("x"),
(false, true) => colours.special_other().paint("T"),
(true, true) => colours.special_other().paint("t"),
}
}
2017-05-20 20:21:17 +00:00
}
2017-05-20 20:49:00 +00:00
pub trait Colours {
2017-08-26 22:53:47 +00:00
fn dash(&self) -> Style;
2017-08-26 22:53:47 +00:00
fn user_read(&self) -> Style;
fn user_write(&self) -> Style;
fn user_execute_file(&self) -> Style;
fn user_execute_other(&self) -> Style;
2017-08-26 22:53:47 +00:00
fn group_read(&self) -> Style;
fn group_write(&self) -> Style;
fn group_execute(&self) -> Style;
2017-08-26 22:53:47 +00:00
fn other_read(&self) -> Style;
fn other_write(&self) -> Style;
fn other_execute(&self) -> Style;
2017-08-26 22:53:47 +00:00
fn special_user_file(&self) -> Style;
fn special_other(&self) -> Style;
fn attribute(&self) -> Style;
}
2017-05-20 20:49:00 +00:00
2017-05-20 20:21:17 +00:00
#[cfg(test)]
#[allow(unused_results)]
pub mod test {
use super::Colours;
2018-12-07 23:43:31 +00:00
use crate::output::cell::TextCellContents;
use crate::fs::fields as f;
2017-05-20 20:21:17 +00:00
use ansi_term::Colour::*;
use ansi_term::Style;
2017-08-26 22:53:47 +00:00
struct TestColours;
2017-08-26 22:53:47 +00:00
impl Colours for TestColours {
2017-08-26 22:53:47 +00:00
fn dash(&self) -> Style { Fixed(11).normal() }
fn user_read(&self) -> Style { Fixed(101).normal() }
fn user_write(&self) -> Style { Fixed(102).normal() }
fn user_execute_file(&self) -> Style { Fixed(103).normal() }
fn user_execute_other(&self) -> Style { Fixed(113).normal() }
fn group_read(&self) -> Style { Fixed(104).normal() }
fn group_write(&self) -> Style { Fixed(105).normal() }
fn group_execute(&self) -> Style { Fixed(106).normal() }
fn other_read(&self) -> Style { Fixed(107).normal() }
fn other_write(&self) -> Style { Fixed(108).normal() }
fn other_execute(&self) -> Style { Fixed(109).normal() }
fn special_user_file(&self) -> Style { Fixed(110).normal() }
fn special_other(&self) -> Style { Fixed(111).normal() }
fn attribute(&self) -> Style { Fixed(112).normal() }
}
2017-05-20 20:21:17 +00:00
#[test]
fn negate() {
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(&TestColours, false).into())
2017-05-20 20:21:17 +00:00
}
#[test]
fn affirm() {
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(&TestColours, true).into())
}
#[test]
fn specials() {
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(110).paint("s"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(111).paint("s"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(111).paint("t"),
]);
assert_eq!(expected, bits.render(&TestColours, true).into())
}
#[test]
fn extra_specials() {
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(111).paint("S"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(111).paint("S"),
Fixed(11).paint("-"), Fixed(11).paint("-"), Fixed(111).paint("T"),
]);
assert_eq!(expected, bits.render(&TestColours, true).into())
2017-05-20 20:21:17 +00:00
}
}