From a2901c63cf5c9f77aec8625f72a1f7b4338569af Mon Sep 17 00:00:00 2001 From: Benjamin Sago Date: Tue, 30 May 2017 15:31:24 +0100 Subject: [PATCH] Render higher permission bits Unlike the others, setuid/setgid/sticky get merged with user/group/other execute in the rendered Permissions cell. So there had to be a bit of code change done to make sure that none of the bits clashed. --- src/output/colours.rs | 11 +++- src/output/render/permissions.rs | 100 ++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 15 deletions(-) diff --git a/src/output/colours.rs b/src/output/colours.rs index 2797386..023a203 100644 --- a/src/output/colours.rs +++ b/src/output/colours.rs @@ -62,7 +62,10 @@ pub struct Permissions { pub other_write: Style, pub other_execute: Style, - pub attribute: Style, + pub special_user_file: Style, + pub special_other: Style, + + pub attribute: Style, } #[derive(Clone, Copy, Debug, Default, PartialEq)] @@ -138,12 +141,18 @@ impl Colours { user_write: Red.bold(), user_execute_file: Green.bold().underline(), user_execute_other: Green.bold(), + group_read: Yellow.normal(), group_write: Red.normal(), group_execute: Green.normal(), + other_read: Yellow.normal(), other_write: Red.normal(), other_execute: Green.normal(), + + special_user_file: Purple.normal(), + special_other: Purple.normal(), + attribute: Style::default(), }, diff --git a/src/output/render/permissions.rs b/src/output/render/permissions.rs index aa6decb..a338202 100644 --- a/src/output/render/permissions.rs +++ b/src/output/render/permissions.rs @@ -6,11 +6,8 @@ use ansi_term::{ANSIString, Style}; impl f::PermissionsPlus { pub fn render(&self, colours: &Colours) -> TextCell { - let x_colour = if self.file_type.is_regular_file() { colours.perms.user_execute_file } - else { colours.perms.user_execute_other }; - let mut chars = vec![ self.file_type.render(colours) ]; - chars.extend(self.permissions.render(colours, x_colour)); + chars.extend(self.permissions.render(colours, self.file_type.is_regular_file())); if self.xattrs { chars.push(colours.perms.attribute.paint("@")); @@ -27,7 +24,7 @@ impl f::PermissionsPlus { } impl f::Permissions { - pub fn render(&self, colours: &Colours, x_colour: Style) -> Vec> { + pub fn render(&self, colours: &Colours, is_regular_file: bool) -> Vec> { let bit = |bit, chr: &'static str, style: Style| { if bit { style.paint(chr) } else { colours.punctuation.paint("-") } }; @@ -35,15 +32,44 @@ impl f::Permissions { vec![ bit(self.user_read, "r", colours.perms.user_read), bit(self.user_write, "w", colours.perms.user_write), - bit(self.user_execute, "x", x_colour), + 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), - bit(self.group_execute, "x", colours.perms.group_execute), + self.group_execute_bit(colours), bit(self.other_read, "r", colours.perms.other_read), bit(self.other_write, "w", colours.perms.other_write), - bit(self.other_execute, "x", colours.perms.other_execute), + 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"), + } + } } impl f::Type { @@ -76,7 +102,7 @@ pub mod test { #[test] fn negate() { let mut details = Details::default(); - details.colours.punctuation = Fixed(44).normal(); + details.colours.punctuation = Fixed(11).normal(); let bits = f::Permissions { user_read: false, user_write: false, user_execute: false, setuid: false, @@ -85,12 +111,12 @@ pub mod test { }; let expected = TextCellContents::from(vec![ - Fixed(44).paint("-"), Fixed(44).paint("-"), Fixed(44).paint("-"), - Fixed(44).paint("-"), Fixed(44).paint("-"), Fixed(44).paint("-"), - Fixed(44).paint("-"), Fixed(44).paint("-"), Fixed(44).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("-"), Fixed(11).paint("-"), ]); - assert_eq!(expected, bits.render(&details.colours, Fixed(66).normal()).into()) + assert_eq!(expected, bits.render(&details.colours, false).into()) } @@ -99,6 +125,7 @@ pub mod test { let mut details = Details::default(); details.colours.perms.user_read = Fixed(101).normal(); details.colours.perms.user_write = Fixed(102).normal(); + details.colours.perms.user_execute_file = Fixed(103).normal(); details.colours.perms.group_read = Fixed(104).normal(); details.colours.perms.group_write = Fixed(105).normal(); @@ -120,6 +147,51 @@ pub mod test { Fixed(107).paint("r"), Fixed(108).paint("w"), Fixed(109).paint("x"), ]); - assert_eq!(expected, bits.render(&details.colours, Fixed(103).normal()).into()) + assert_eq!(expected, bits.render(&details.colours, true).into()) + } + + + #[test] + fn specials() { + let mut details = Details::default(); + details.colours.punctuation = Fixed(11).normal(); + details.colours.perms.special_user_file = Fixed(77).normal(); + details.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(&details.colours, true).into()) + } + + + #[test] + fn extra_specials() { + let mut details = Details::default(); + details.colours.punctuation = Fixed(11).normal(); + details.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(&details.colours, true).into()) } }