Просмотр исходного кода

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.
Benjamin Sago 8 лет назад
Родитель
Сommit
a2901c63cf
2 измененных файлов с 96 добавлено и 15 удалено
  1. 10 1
      src/output/colours.rs
  2. 86 14
      src/output/render/permissions.rs

+ 10 - 1
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(),
             },
 

+ 86 - 14
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<ANSIString<'static>> {
+    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("-") }
         };
@@ -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())
     }
 }