summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzwPapEr <zw.paper@gmail.com>2019-11-02 15:42:42 +0800
committerAbin Simon <abinsimon10@gmail.com>2020-01-11 14:17:44 +0530
commit0ebb39d60cc498cf92c09e8b3fa46316873941b6 (patch)
tree96fb9ce7d12402cc06937a3422fc798f04939bc6
parent87e87d87cdf91d7e8a3f385b0a5beb96ddbd8824 (diff)
impl showing inode by setting blocks
working on https://github.com/Peltoche/lsd/issues/276
-rw-r--r--src/app.rs11
-rw-r--r--src/display.rs3
-rw-r--r--src/flags.rs2
-rw-r--r--src/meta/inode.rs55
-rw-r--r--src/meta/mod.rs5
5 files changed, 75 insertions, 1 deletions
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<ANSIString> = 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<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),