diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-11-27 16:57:21 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-11-28 10:37:40 +0200 |
commit | aa6709b2f657a964c2af04f6370e7eb7c117bf9e (patch) | |
tree | 9e0f5ba56f45eb24d286ac38a67b27ed0899f9d6 /src | |
parent | b5b5884097219d77aa0b4cd6ad4d3a9c1407f5a6 (diff) | |
download | summain-rs-aa6709b2f657a964c2af04f6370e7eb7c117bf9e.tar.gz |
feat: implement Summain in Rust
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 70 |
2 files changed, 69 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ + diff --git a/src/main.rs b/src/main.rs index e7a11a9..fd23eb8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,69 @@ -fn main() { - println!("Hello, world!"); +use anyhow::Context; +use serde::Serialize; +use std::fs::symlink_metadata; +use std::fs::Metadata; +use std::os::linux::fs::MetadataExt; +use std::path::{Path, PathBuf}; +use structopt::StructOpt; + +fn main() -> anyhow::Result<()> { + let mut opt = Opt::from_args(); + opt.pathnames[..].sort(); + for pathname in opt.pathnames { + report(&pathname).with_context(|| format!("{}", pathname.display()))? + } + Ok(()) +} + +#[derive(StructOpt, Debug)] +struct Opt { + #[structopt(parse(from_os_str))] + pathnames: Vec<PathBuf>, +} + +#[derive(Serialize, Debug)] +struct Entry { + path: PathBuf, + atime: i64, + atime_nsec: i64, + #[serde(with = "mode")] + mode: u32, + mtime: i64, + mtime_nsec: i64, + nlink: u64, + size: Option<u64>, +} + +impl Entry { + fn new(path: &Path, m: Metadata) -> Self { + Self { + path: path.to_path_buf(), + atime: m.st_atime(), + atime_nsec: m.st_atime_nsec(), + mode: m.st_mode(), + mtime: m.st_mtime(), + mtime_nsec: m.st_mtime_nsec(), + nlink: m.st_nlink(), + size: if m.is_dir() { None } else { Some(m.st_size()) }, + } + } +} + +fn report(pathname: &Path) -> anyhow::Result<()> { + let m = symlink_metadata(pathname)?; + let e = Entry::new(pathname, m); + println!("{}", serde_yaml::to_string(&e)?); + Ok(()) +} + +mod mode { + use serde::{self, Serializer}; + + pub fn serialize<S>(mode: &u32, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let s = unix_mode::to_string(*mode); + serializer.serialize_str(&s) + } } |