From 0ebb39d60cc498cf92c09e8b3fa46316873941b6 Mon Sep 17 00:00:00 2001 From: zwPapEr Date: Sat, 2 Nov 2019 15:42:42 +0800 Subject: impl showing inode by setting blocks working on https://github.com/Peltoche/lsd/issues/276 --- src/app.rs | 11 ++++++++++- src/display.rs | 3 +++ src/flags.rs | 2 ++ src/meta/inode.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/meta/mod.rs | 5 +++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/meta/inode.rs diff --git a/src/app.rs b/src/app.rs index 3078aae..e97df00 100644 --- a/src/app.rs +++ b/src/app.rs @@ -178,7 +178,16 @@ pub fn build() -> App<'static, 'static> { .multiple(true) .number_of_values(1) .require_delimiter(true) - .possible_values(&["permission", "user", "group", "size", "date", "name"]) + .possible_values(&[ + "permission", + "user", + "group", + "size", + "date", + "name", + "inode", + ]) + .default_value("permission,user,group,size,date,name") .help("Specify the blocks that will be displayed and in what order"), ) .arg( diff --git a/src/display.rs b/src/display.rs index 93179d8..b3d8e5f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -221,6 +221,9 @@ fn get_output<'a>( let mut strings: Vec = Vec::new(); for block in flags.blocks.iter() { match block { + Block::INode => { + strings.push(meta.inode.render(colors)); + } Block::Permission => { let s: &[ColoredString] = &[ meta.file_type.render(colors), diff --git a/src/flags.rs b/src/flags.rs index d8e8c43..6c6de7f 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -205,6 +205,7 @@ pub enum Block { SizeValue, Date, Name, + INode, } impl<'a> From<&'a str> for Block { fn from(block: &'a str) -> Self { @@ -217,6 +218,7 @@ impl<'a> From<&'a str> for Block { "size_value" => Block::SizeValue, "date" => Block::Date, "name" => Block::Name, + "inode" => Block::INode, _ => panic!("invalid \"time\" flag: {}", block), } } diff --git a/src/meta/inode.rs b/src/meta/inode.rs new file mode 100644 index 0000000..bf30273 --- /dev/null +++ b/src/meta/inode.rs @@ -0,0 +1,55 @@ +use crate::color::{ColoredString, Colors, Elem}; +use std::fs::Metadata; + +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +pub struct INode { + index: u64, +} + +impl<'a> From<&'a Metadata> for INode { + #[cfg(unix)] + fn from(meta: &Metadata) -> Self { + use std::os::unix::fs::MetadataExt; + + let index = meta.ino(); + + Self { index: index } + } + + #[cfg(windows)] + fn from(_: &Metadata) -> Self { + panic!("Cannot get inode on Windows") + } +} + +impl INode { + pub fn render(&self, colors: &Colors) -> ColoredString { + colors.colorize(self.index.to_string(), &Elem::SymLink) + } +} + +#[cfg(test)] +mod tests { + use super::INode; + use std::env; + use std::io; + use std::path::Path; + use std::process::{Command, ExitStatus}; + + #[cfg(unix)] + fn cross_platform_touch(path: &Path) -> io::Result { + Command::new("touch").arg(&path).status() + } + + #[test] + fn test_inode_no_zero() { + let mut file_path = env::temp_dir(); + file_path.push("inode.tmp"); + + let success = cross_platform_touch(&file_path).unwrap().success(); + assert!(success, "failed to exec touch"); + + let inode = INode::from(&file_path.metadata().unwrap()); + assert_ne!(inode.index, 0); + } +} diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 69bc34f..2ecc472 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -1,6 +1,7 @@ mod date; mod filetype; mod indicator; +mod inode; mod name; mod owner; mod permissions; @@ -13,6 +14,7 @@ mod windows_utils; pub use self::date::Date; pub use self::filetype::FileType; pub use self::indicator::Indicator; +pub use self::inode::INode; pub use self::name::Name; pub use self::owner::Owner; pub use self::permissions::Permissions; @@ -40,6 +42,7 @@ pub struct Meta { pub size: Size, pub symlink: SymLink, pub indicator: Indicator, + pub inode: INode, pub content: Option>, } @@ -211,8 +214,10 @@ impl Meta { let file_type = FileType::new(&metadata, &permissions); let name = Name::new(&path, file_type); + let inode = INode::from(&metadata); Ok(Self { + inode, path: path.to_path_buf(), symlink: SymLink::from(path.as_path()), size: Size::from(&metadata), -- cgit v1.2.3