소스 검색

Now move permissions

Benjamin Sago 8 년 전
부모
커밋
3f8b547f2d
3개의 변경된 파일137개의 추가작업 그리고 80개의 파일을 삭제
  1. 1 80
      src/output/details.rs
  2. 1 0
      src/output/mod.rs
  3. 135 0
      src/output/permissions.rs

+ 1 - 80
src/output/details.rs

@@ -83,8 +83,6 @@ use std::path::PathBuf;
 use std::string::ToString;
 use std::sync::{Arc, Mutex, MutexGuard};
 
-use ansi_term::Style;
-
 use datetime::fmt::DateFormat;
 use datetime::{LocalDateTime, DatePiece};
 use datetime::TimeZone;
@@ -498,7 +496,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
         use output::column::TimeType::*;
 
         match *column {
-            Column::Permissions          => self.render_permissions(file.type_char(), file.permissions(), xattrs),
+            Column::Permissions          => file.permissions().render(&self.opts.colours, file.type_char(), xattrs),
             Column::FileSize(fmt)        => self.render_size(file.size(), fmt),
             Column::Timestamp(Modified)  => self.render_time(file.modified_time()),
             Column::Timestamp(Created)   => self.render_time(file.created_time()),
@@ -512,56 +510,6 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
         }
     }
 
-    fn render_permissions(&self, file_type: f::Type, permissions: f::Permissions, xattrs: bool) -> TextCell {
-        let perms = self.opts.colours.perms;
-        let types = self.opts.colours.filetypes;
-
-        let bit = |bit, chr: &'static str, style: Style| {
-            if bit { style.paint(chr) } else { self.opts.colours.punctuation.paint("-") }
-        };
-
-        let type_char = match file_type {
-            f::Type::File       => types.normal.paint("."),
-            f::Type::Directory  => types.directory.paint("d"),
-            f::Type::Pipe       => types.pipe.paint("|"),
-            f::Type::Link       => types.symlink.paint("l"),
-            f::Type::CharDevice => types.device.paint("c"),
-            f::Type::BlockDevice => types.device.paint("b"),
-            f::Type::Socket     => types.socket.paint("s"),
-            f::Type::Special    => types.special.paint("?"),
-        };
-
-        let x_colour = if file_type.is_regular_file() { perms.user_execute_file }
-                                                 else { perms.user_execute_other };
-
-        let mut chars = vec![
-            type_char,
-            bit(permissions.user_read,     "r", perms.user_read),
-            bit(permissions.user_write,    "w", perms.user_write),
-            bit(permissions.user_execute,  "x", x_colour),
-            bit(permissions.group_read,    "r", perms.group_read),
-            bit(permissions.group_write,   "w", perms.group_write),
-            bit(permissions.group_execute, "x", perms.group_execute),
-            bit(permissions.other_read,    "r", perms.other_read),
-            bit(permissions.other_write,   "w", perms.other_write),
-            bit(permissions.other_execute, "x", perms.other_execute),
-        ];
-
-        if xattrs {
-            chars.push(perms.attribute.paint("@"));
-        }
-
-        // As these are all ASCII characters, we can guarantee that they’re
-        // all going to be one character wide, and don’t need to compute the
-        // cell’s display width.
-        let width = DisplayWidth::from(chars.len());
-
-        TextCell {
-            contents: chars.into(),
-            width:    width,
-        }
-    }
-
     fn render_links(&self, links: f::Links) -> TextCell {
         let style = if links.multiple { self.opts.colours.links.multi_link_file }
                                  else { self.opts.colours.links.normal };
@@ -741,30 +689,3 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
         cells
     }
 }
-
-
-#[cfg(test)]
-pub mod test {
-    use super::Environment;
-
-    use users::mock::MockUsers;
-    use datetime::fmt::DateFormat;
-
-    impl Default for Environment<MockUsers> {
-        fn default() -> Self {
-            use locale;
-            use users::mock::MockUsers;
-            use std::sync::Mutex;
-
-            Environment {
-                current_year:  1234,
-                numeric:       locale::Numeric::english(),
-                time:          locale::Time::english(),
-                date_and_time: DateFormat::parse("{2>:D} {4>:M} {2>:h}:{02>:m}").unwrap(),
-                date_and_year: DateFormat::parse("{2>:D} {:M} {5>:Y}").unwrap(),
-                tz:            None,
-                users:         Mutex::new(MockUsers::with_current_uid(0)),
-            }
-        }
-    }
-}

+ 1 - 0
src/output/mod.rs

@@ -18,3 +18,4 @@ pub mod file_name;
 mod escape;
 mod users;
 mod groups;
+mod permissions;

+ 135 - 0
src/output/permissions.rs

@@ -0,0 +1,135 @@
+use fs::fields as f;
+use output::colours::Colours;
+use output::cell::{TextCell, DisplayWidth};
+use ansi_term::Style;
+
+
+impl f::Permissions {
+    pub fn render(&self, colours: &Colours, file_type: f::Type, xattrs: bool) -> TextCell {
+       let bit = |bit, chr: &'static str, style: Style| {
+           if bit { style.paint(chr) } else { colours.punctuation.paint("-") }
+       };
+
+       let type_char = match file_type {
+           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("?"),
+       };
+
+       let x_colour = if file_type.is_regular_file() { colours.perms.user_execute_file }
+                                                else { colours.perms.user_execute_other };
+
+       let mut chars = vec![
+           type_char,
+           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),
+           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),
+           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),
+       ];
+
+       if xattrs {
+           chars.push(colours.perms.attribute.paint("@"));
+       }
+
+       // As these are all ASCII characters, we can guarantee that they’re
+       // all going to be one character wide, and don’t need to compute the
+       // cell’s display width.
+       let width = DisplayWidth::from(chars.len());
+
+       TextCell {
+           contents: chars.into(),
+           width:    width,
+       }
+   }
+}
+
+
+#[cfg(test)]
+#[allow(unused_results)]
+pub mod test {
+    use output::details::Details;
+
+    use fs::fields as f;
+    use output::cell::TextCell;
+
+    use users::{User, Group};
+    use users::mock::MockUsers;
+    use users::os::unix::GroupExt;
+    use ansi_term::Colour::*;
+
+
+    #[test]
+    fn named() {
+        let mut details = Details::default();
+        details.colours.users.group_not_yours = Fixed(101).normal();
+
+        let mut users = MockUsers::with_current_uid(1000);
+        users.add_group(Group::new(100, "folk"));
+
+        let group = f::Group(100);
+        let expected = TextCell::paint_str(Fixed(101).normal(), "folk");
+        assert_eq!(expected, group.render(&details.colours, &users))
+    }
+
+    #[test]
+    fn unnamed() {
+        let mut details = Details::default();
+        details.colours.users.group_not_yours = Fixed(87).normal();
+
+        let users = MockUsers::with_current_uid(1000);
+
+        let group = f::Group(100);
+        let expected = TextCell::paint_str(Fixed(87).normal(), "100");
+        assert_eq!(expected, group.render(&details.colours, &users));
+    }
+
+    #[test]
+    fn primary() {
+        let mut details = Details::default();
+        details.colours.users.group_yours = Fixed(64).normal();
+
+        let mut users = MockUsers::with_current_uid(2);
+        users.add_user(User::new(2, "eve", 100));
+        users.add_group(Group::new(100, "folk"));
+
+        let group = f::Group(100);
+        let expected = TextCell::paint_str(Fixed(64).normal(), "folk");
+        assert_eq!(expected, group.render(&details.colours, &users))
+    }
+
+    #[test]
+    fn secondary() {
+        let mut details = Details::default();
+        details.colours.users.group_yours = Fixed(31).normal();
+
+        let mut users = MockUsers::with_current_uid(2);
+        users.add_user(User::new(2, "eve", 666));
+
+        let test_group = Group::new(100, "folk").add_member("eve");
+        users.add_group(test_group);
+
+        let group = f::Group(100);
+        let expected = TextCell::paint_str(Fixed(31).normal(), "folk");
+        assert_eq!(expected, group.render(&details.colours, &users))
+    }
+
+    #[test]
+    fn overflow() {
+        let mut details = Details::default();
+        details.colours.users.group_not_yours = Blue.underline();
+
+        let group = f::Group(2_147_483_648);
+        let expected = TextCell::paint_str(Blue.underline(), "2147483648");
+        assert_eq!(expected, group.render(&details.colours, &MockUsers::with_current_uid(0)));
+    }
+}