From 2ea91652b7822e1ec9ab34657df6627b6d2bdc0c Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Wed, 15 Nov 2023 23:29:11 -0500 Subject: [PATCH] Start work on output collector --- Cargo.lock | 1 + Cargo.toml | 1 + ncdufmt/src/lib.rs | 30 +++++++++++++++++++++------ src/collector.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 ++ src/tar.rs | 4 ++-- 6 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 src/collector.rs diff --git a/Cargo.lock b/Cargo.lock index fc18a40..8a65575 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,7 @@ dependencies = [ "anyhow", "crossbeam", "ncdufmt", + "serde_json", "tar", ] diff --git a/Cargo.toml b/Cargo.toml index 027cda7..48b6047 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,5 @@ members = [ anyhow = "1.0.75" crossbeam = { version = "0.8.2", features = ["crossbeam-channel"] } ncdufmt = {path="./ncdufmt/"} +serde_json = "1.0.108" tar = "0.4.40" diff --git a/ncdufmt/src/lib.rs b/ncdufmt/src/lib.rs index 45ee6e9..7e16431 100644 --- a/ncdufmt/src/lib.rs +++ b/ncdufmt/src/lib.rs @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; // This is based on https://dev.yorhel.nl/ncdu/jsonfmt #[derive(Debug, PartialEq, Clone)] -struct NcduFile { +pub struct NcduFile { pub major_version: MajorVersion, pub minor_version: MinorVersion, pub header_metadata: HeaderMetadata, @@ -125,10 +125,10 @@ pub struct HeaderMetadata { impl HeaderMetadata { /// Construct a HeaderMetadata with the current time - pub fn new(progname: String, progver: String) -> Self { + pub fn new(progname: impl AsRef, progver: impl AsRef) -> Self { Self { - progname, - progver, + progname: progname.as_ref().to_string(), + progver: progver.as_ref().to_string(), timestamp: SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .as_ref() @@ -140,8 +140,8 @@ impl HeaderMetadata { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Directory { - info: InfoBlock, - contents: Vec, + pub info: InfoBlock, + pub contents: Vec, } impl Serialize for Directory { @@ -295,6 +295,24 @@ pub struct InfoBlock { pub extended_info_block: Option, } +impl InfoBlock { + pub fn new(name: impl AsRef) -> Self { + Self { + name: name.as_ref().to_string(), + dev: Default::default(), + asize: Default::default(), + dsize: Default::default(), + hlnkc: Default::default(), + ino: Default::default(), + nlink: Default::default(), + read_error: Default::default(), + excluded: Default::default(), + notreg: Default::default(), + extended_info_block: Default::default(), + } + } +} + #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub struct ExtendedInfoBlock { /// Number, user ID who owns the file. Accepted values are in the range 0 <= uid < 2^31. diff --git a/src/collector.rs b/src/collector.rs new file mode 100644 index 0000000..9cef6ba --- /dev/null +++ b/src/collector.rs @@ -0,0 +1,51 @@ +use std::io::Write; + +use crate::types; +use anyhow::Result; +use ncdufmt::{MajorVersion, MinorVersion, HeaderMetadata, InfoBlock, NcduFile, Directory, FileOrDirectory}; + +/// Builds an ncdu file from a stream +pub fn build_ncdu_file(rx: crossbeam::channel::Receiver/*, _writer: impl Write*/) -> Result { + let mut ret = NcduFile { + major_version: MajorVersion::default(), + minor_version: MinorVersion::default(), + header_metadata: HeaderMetadata::new("test-program", "0.1.1"), + contents: Directory { + info: InfoBlock::new("test-filename.tar".to_string()), + contents: Vec::default(), + } + }; + + while let Ok(entry) = rx.recv() { + let mut e = InfoBlock::new(entry.path.to_string_lossy()); + e.asize = entry.size; + ret.contents.contents.push(FileOrDirectory::File(e) ); + } + + Ok(ret) +} + + + +#[cfg(test)] +mod tests { + use std::fs::File; + + use super::*; + + #[test] + fn simple_tree() { + // Check that this tar file of mine has a Cargo.lock and 10 entries + let reader = File::open("./test-tar.tar").unwrap(); + let (tx, rx) = crossbeam::channel::bounded(100); + + crate::tar::get_entries(tx, reader).unwrap(); + + let ret = build_ncdu_file(rx).unwrap(); + + eprintln!("{ret:#?}"); + eprintln!("{}", serde_json::to_string(&ret).unwrap()); + + panic!(); + } +} diff --git a/src/main.rs b/src/main.rs index 6f6bb31..26427d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ mod tar; mod types; +mod collector; + fn main() { println!("Hello, world!"); } diff --git a/src/tar.rs b/src/tar.rs index f31cf1f..0dc2d36 100644 --- a/src/tar.rs +++ b/src/tar.rs @@ -9,8 +9,8 @@ use tar::Archive; /// /// The tar file must be in a decompressed state pub fn get_entries( - reader: impl Read, tx: crossbeam::channel::Sender, + reader: impl Read, ) -> Result<()> { let mut archive = Archive::new(reader); @@ -38,7 +38,7 @@ mod tests { let reader = File::open("./test-tar.tar").unwrap(); let (tx, rx) = crossbeam::channel::bounded(100); - get_entries(reader, tx).unwrap(); + get_entries(tx, reader).unwrap(); let mut results = vec![]; while let Ok(entry) = rx.recv() {