summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-11-27 16:57:21 +0200
committerLars Wirzenius <liw@liw.fi>2020-11-28 10:37:40 +0200
commitaa6709b2f657a964c2af04f6370e7eb7c117bf9e (patch)
tree9e0f5ba56f45eb24d286ac38a67b27ed0899f9d6 /src
parentb5b5884097219d77aa0b4cd6ad4d3a9c1407f5a6 (diff)
downloadsummain-rs-aa6709b2f657a964c2af04f6370e7eb7c117bf9e.tar.gz
feat: implement Summain in Rust
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs70
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)
+ }
}