From 0d45390b40c4d044420fb2f733d1331d43681ae4 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Tue, 14 Nov 2023 22:54:32 -0500 Subject: [PATCH] Add arncdu --- .gitignore | 1 + Cargo.lock | 109 ++++++++++++++++++++++++++++++++++ Cargo.toml | 18 ++++++ ncdufmt/Cargo.toml | 11 ++++ ncdufmt/src/lib.rs | 145 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 3 + 6 files changed, 287 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 ncdufmt/Cargo.toml create mode 100644 ncdufmt/src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6041e3f --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,109 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arncdu" +version = "0.1.0" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "ncdufmt" +version = "0.1.0" +dependencies = [ + "num-traits", + "serde", + "serde_json", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..fe4dde2 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "arncdu" +version = "0.1.0" +edition = "2021" + +[workspace] +members = [ + ".", + "./ncdufmt/", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# num-traits = "0.2.17" +# serde = { version = "1.0.192", features = ["derive"] } +# serde_json = "1.0.108" +# tar = "0.4.40" diff --git a/ncdufmt/Cargo.toml b/ncdufmt/Cargo.toml new file mode 100644 index 0000000..afa7b34 --- /dev/null +++ b/ncdufmt/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ncdufmt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +num-traits = "0.2.17" +serde = { version = "1.0.192", features = ["derive"] } +serde_json = "1.0.108" diff --git a/ncdufmt/src/lib.rs b/ncdufmt/src/lib.rs new file mode 100644 index 0000000..f24d60d --- /dev/null +++ b/ncdufmt/src/lib.rs @@ -0,0 +1,145 @@ +// use crate::async_temp_buf::AsyncTempBuf; +// use anyhow::Result; +use std::time::{Duration, SystemTime}; +use std::ops::Not; +use num_traits::identities::Zero; +use num_traits::identities::One; +// use std::{os::unix::prelude::MetadataExt, path::Path}; + +use serde::{Deserialize, Serialize}; +// use tokio::fs::metadata; + +// This is based on https://dev.yorhel.nl/ncdu/jsonfmt + +pub type DeviceId = u64; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Header { + pub majorver: u64, + pub minorver: u64, + pub header_metadata: HeaderMetadata, +} + +impl Default for Header { + fn default() -> Self { + Self { + majorver: 1, + minorver: 2, + header_metadata: HeaderMetadata::default(), + } + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct HeaderMetadata { + pub progname: String, + pub progver: String, + pub timestamp: u64, +} + +impl Default for HeaderMetadata { + fn default() -> Self { + Self { + progname: String::from("ncdu"), + progver: String::from("1.17"), + timestamp: SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .as_ref() + .map(Duration::as_secs) + .unwrap_or(0_u64), + } + } +} + +/// String. Set if this file or directory is to be excluded from calculation for some reason. +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "lowercase")] +pub enum Excluded { + /// If the path matched an exclude pattern. + Pattern, + /// If the item is on a different device/filesystem. + OtherFs, + /// If the item has been excluded with --exclude-kernfs (since ncdu 1.15). + KernFs, + /// If the item is a firmlink and hasn’t been followed with --follow-firmlinks (since ncdu 1.15). + FrmLink, +} + +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct InfoBlock { + /// Basename + /// TODO: Max 32768 bytes + pub name: String, + + /// Device ID. A unique ID within the context of the exported dump. Could be a serialization of lstat().st_dev, but could be randomly generated and used within this file + /// + /// Accepted values are in the range of 0 <= dev < 2^64. + pub dev: DeviceId, + + /// Apparent filesize + /// Reported by lstat().st_size. If absent, 0 is assumed. Accepted values are in the range of 0 <= asize < 2^63 + #[serde(skip_serializing_if = "Zero::is_zero")] + pub asize: u64, + + /// Size of the file, as consumed on the disk. + /// This is obtained through lstat().st_blocks*S_BLKSIZE. If absent, 0 is assumed. Accepted values are in the range of 0 <= dsize < 2^63. + #[serde(skip_serializing_if = "Zero::is_zero")] + pub dsize: u64, + + /// Hardlinks + /// true if this is a file with lstat().st_nlink > 1 + #[serde(skip_serializing_if = "Not::not")] + pub hlnkc: bool, + + /// Inode number as reported by lstat().st_ino. Together with the Device ID this uniquely identifies a file in this dump. + /// In the case of hard links, two objects may appear with the same (dev,ino) combination. As of ncdu 1.16, this field is only exported if st_nlink > 1. A value of 0 is assumed if this field is absent, which is fine as long as the hlnkc field is false and nlink is 1, otherwise everything with the same dev and empty ino values will be considered as a single hardlinked file. Accepted values are in the range of 0 <= ino < 2^64. + + #[serde(skip_serializing_if = "Zero::is_zero")] + pub ino: u64, + + /// Number of hardlinks to this inode. The value of lstat().st_nlink + /// Accepted values are in the range 1 <= nlink < 2^32. If absent, 1 is assumed. + + #[serde(skip_serializing_if = "One::is_one")] + pub nlink: u64, + + /// Something went wrong while reading this entry + /// For files, this indicates that the lstat() call failed. For directories, this means that an error occurred while obtaining the file listing, and some items may be missing + + #[serde(skip_serializing_if = "Not::not")] + pub read_error: bool, + + // TODO: Implement this one + /// String. Set if this file or directory is to be excluded from calculation for some reason. The following values are recognized: + /// "pattern" + /// If the path matched an exclude pattern. + /// "otherfs" + /// If the item is on a different device/filesystem. + /// "kernfs" + /// If the item has been excluded with --exclude-kernfs (since ncdu 1.15). + /// "frmlink" + /// If the item is a firmlink and hasn’t been followed with --follow-firmlinks (since ncdu 1.15). + /// Excluded items may still be included in the export, but only by name. size, asize and other information may be absent. If this item was excluded by a pattern, ncdu will not do an lstat() on it, and may thus report this item as a file even if it is a directory. + #[serde(skip_serializing_if = "Option::is_none")] + pub excluded: Option, + + /// This is true if neither S_ISREG() nor S_ISDIR() evaluates to true. I.e. this is a symlink, character device, block device, FIFO, socket, or whatever else your system may support. + #[serde(skip_serializing_if = "Not::not")] + pub notreg: bool, + + /// Extended info if it was specified to generate + #[serde(skip_serializing_if = "Option::is_none", flatten)] + pub extended_info_block: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ExtendedInfoBlock { + /// Number, user ID who owns the file. Accepted values are in the range 0 <= uid < 2^31. + uid: u32, + /// Number, group ID who owns the file. Accepted values are in the range 0 <= uid < 2^31. + gid: u32, + /// Number, the raw file mode as returned by lstat(3). For Linux systems, see inode(7) for the interpretation of this field. Accepted range: 0 <= mode < 2^16. + mode: u16, + /// Number, last modification time as a UNIX timestamp. Accepted range: 0 <= mtime < 2^64. As of ncdu 1.16, this number may also include an (infinite precision) decimal part for fractional seconds, though the decimal part is (currently) discarded during import. + mtime: u64, +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}