diff options
Diffstat (limited to 'src/meta')
-rw-r--r-- | src/meta/inode.rs | 55 | ||||
-rw-r--r-- | src/meta/mod.rs | 5 |
2 files changed, 60 insertions, 0 deletions
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<ExitStatus> { + 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<Vec<Meta>>, } @@ -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), |