diff --git a/src/fs/mod.rs b/src/fs/mod.rs index 34e6f29..3f0c927 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -27,7 +27,7 @@ extern crate bytesize; #[cfg(any(unix, macos, linux))] extern crate users; -use crate::utils::time_to_str; +use crate::utils::{fmt_pex, time_to_str}; use bytesize::ByteSize; use std::path::PathBuf; @@ -101,51 +101,7 @@ impl std::fmt::Display for FsEntry { match dir.unix_pex { None => mode.push_str("?????????"), Some((owner, group, others)) => { - let read: u8 = (owner >> 2) & 0x1; - let write: u8 = (owner >> 1) & 0x1; - let exec: u8 = owner & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (group >> 2) & 0x1; - let write: u8 = (group >> 1) & 0x1; - let exec: u8 = group & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (others >> 2) & 0x1; - let write: u8 = (others >> 1) & 0x1; - let exec: u8 = others & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); + mode.push_str(fmt_pex(owner, group, others).as_str()) } } // Get username @@ -192,51 +148,7 @@ impl std::fmt::Display for FsEntry { match file.unix_pex { None => mode.push_str("?????????"), Some((owner, group, others)) => { - let read: u8 = (owner >> 2) & 0x1; - let write: u8 = (owner >> 1) & 0x1; - let exec: u8 = owner & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (group >> 2) & 0x1; - let write: u8 = (group >> 1) & 0x1; - let exec: u8 = group & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (others >> 2) & 0x1; - let write: u8 = (others >> 1) & 0x1; - let exec: u8 = others & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); + mode.push_str(fmt_pex(owner, group, others).as_str()) } } // Get username @@ -293,51 +205,7 @@ impl std::fmt::Display for FsEntry { match dir.unix_pex { None => mode.push_str("?????????"), Some((owner, group, others)) => { - let read: u8 = (owner >> 2) & 0x1; - let write: u8 = (owner >> 1) & 0x1; - let exec: u8 = owner & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (group >> 2) & 0x1; - let write: u8 = (group >> 1) & 0x1; - let exec: u8 = group & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (others >> 2) & 0x1; - let write: u8 = (others >> 1) & 0x1; - let exec: u8 = others & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); + mode.push_str(fmt_pex(owner, group, others).as_str()) } } // Get username @@ -378,51 +246,7 @@ impl std::fmt::Display for FsEntry { match file.unix_pex { None => mode.push_str("?????????"), Some((owner, group, others)) => { - let read: u8 = (owner >> 2) & 0x1; - let write: u8 = (owner >> 1) & 0x1; - let exec: u8 = owner & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (group >> 2) & 0x1; - let write: u8 = (group >> 1) & 0x1; - let exec: u8 = group & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); - let read: u8 = (others >> 2) & 0x1; - let write: u8 = (others >> 1) & 0x1; - let exec: u8 = others & 0x1; - mode.push_str(match read { - 1 => "r", - _ => "-", - }); - mode.push_str(match write { - 1 => "w", - _ => "-", - }); - mode.push_str(match exec { - 1 => "x", - _ => "-", - }); + mode.push_str(fmt_pex(owner, group, others).as_str()) } } // Get username diff --git a/src/utils.rs b/src/utils.rs index d283ff9..b3e17fb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -141,6 +141,59 @@ pub fn parse_remote_opt( Ok((address, port, protocol, username)) } +/// ### fmt_pex +/// +/// Convert 3 bytes of permissions value into ls notation (e.g. rwx-wx--x) +pub fn fmt_pex(owner: u8, group: u8, others: u8) -> String { + let mut mode: String = String::with_capacity(9); + let read: u8 = (owner >> 2) & 0x1; + let write: u8 = (owner >> 1) & 0x1; + let exec: u8 = owner & 0x1; + mode.push_str(match read { + 1 => "r", + _ => "-", + }); + mode.push_str(match write { + 1 => "w", + _ => "-", + }); + mode.push_str(match exec { + 1 => "x", + _ => "-", + }); + let read: u8 = (group >> 2) & 0x1; + let write: u8 = (group >> 1) & 0x1; + let exec: u8 = group & 0x1; + mode.push_str(match read { + 1 => "r", + _ => "-", + }); + mode.push_str(match write { + 1 => "w", + _ => "-", + }); + mode.push_str(match exec { + 1 => "x", + _ => "-", + }); + let read: u8 = (others >> 2) & 0x1; + let write: u8 = (others >> 1) & 0x1; + let exec: u8 = others & 0x1; + mode.push_str(match read { + 1 => "r", + _ => "-", + }); + mode.push_str(match write { + 1 => "w", + _ => "-", + }); + mode.push_str(match exec { + 1 => "x", + _ => "-", + }); + mode +} + /// ### instant_to_str /// /// Format a `Instant` into a time string @@ -240,7 +293,7 @@ mod tests { assert_eq!(result.1, 21); // Fallback to ftp default assert_eq!(result.2, FileTransferProtocol::Ftp(false)); assert!(result.3.is_none()); // Doesn't fall back - // Protocol + // Protocol let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("scp://172.26.104.1")) .ok() @@ -249,7 +302,7 @@ mod tests { assert_eq!(result.1, 22); // Fallback to scp default assert_eq!(result.2, FileTransferProtocol::Scp); assert!(result.3.is_none()); // Doesn't fall back - // Protocol + user + // Protocol + user let result: (String, u16, FileTransferProtocol, Option) = parse_remote_opt(&String::from("ftps://anon@172.26.104.1")) .ok() @@ -274,6 +327,18 @@ mod tests { assert!(parse_remote_opt(&String::from("172.26.104.1:abc")).is_err()); // Bad port } + #[test] + fn test_utils_fmt_pex() { + assert_eq!(fmt_pex(7, 7, 7), String::from("rwxrwxrwx")); + assert_eq!(fmt_pex(7, 5, 5), String::from("rwxr-xr-x")); + assert_eq!(fmt_pex(6, 6, 6), String::from("rw-rw-rw-")); + assert_eq!(fmt_pex(6, 4, 4), String::from("rw-r--r--")); + assert_eq!(fmt_pex(6, 0, 0), String::from("rw-------")); + assert_eq!(fmt_pex(0, 0, 0), String::from("---------")); + assert_eq!(fmt_pex(4, 4, 4), String::from("r--r--r--")); + assert_eq!(fmt_pex(1, 2, 1), String::from("--x-w---x")); + } + #[test] fn test_utils_time_to_str() { let system_time: SystemTime = SystemTime::from(SystemTime::UNIX_EPOCH); @@ -290,28 +355,36 @@ mod tests { lstime_to_systime("Nov 5 16:32", "%b %d %Y", "%b %d %H:%M") .ok() .unwrap() - .duration_since(SystemTime::UNIX_EPOCH).ok().unwrap(), + .duration_since(SystemTime::UNIX_EPOCH) + .ok() + .unwrap(), Duration::from_secs(1604593920) ); assert_eq!( lstime_to_systime("Dec 2 21:32", "%b %d %Y", "%b %d %H:%M") .ok() .unwrap() - .duration_since(SystemTime::UNIX_EPOCH).ok().unwrap(), + .duration_since(SystemTime::UNIX_EPOCH) + .ok() + .unwrap(), Duration::from_secs(1606944720) ); assert_eq!( lstime_to_systime("Nov 5 2018", "%b %d %Y", "%b %d %H:%M") .ok() .unwrap() - .duration_since(SystemTime::UNIX_EPOCH).ok().unwrap(), + .duration_since(SystemTime::UNIX_EPOCH) + .ok() + .unwrap(), Duration::from_secs(1541376000) ); assert_eq!( lstime_to_systime("Mar 18 2018", "%b %d %Y", "%b %d %H:%M") .ok() .unwrap() - .duration_since(SystemTime::UNIX_EPOCH).ok().unwrap(), + .duration_since(SystemTime::UNIX_EPOCH) + .ok() + .unwrap(), Duration::from_secs(1521331200) ); // bad cases