Skip to content

Commit

Permalink
Pull out all modules into files
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Thiel committed Jun 1, 2019
1 parent 961b743 commit 8b2ef49
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 183 deletions.
72 changes: 72 additions & 0 deletions src/aggregate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::{WalkOptions, WalkResult};
use failure::Error;
use std::borrow::Cow;
use std::{io, path::Path};

pub fn aggregate(
mut out: impl io::Write,
options: WalkOptions,
compute_total: bool,
paths: impl IntoIterator<Item = impl AsRef<Path>>,
) -> Result<WalkResult, Error> {
let mut res = WalkResult::default();
let mut total = 0;
let mut num_roots = 0;
for path in paths.into_iter() {
num_roots += 1;
let mut num_bytes = 0u64;
let mut num_errors = 0u64;
for entry in options.iter_from_path(path.as_ref()) {
match entry {
Ok(entry) => {
num_bytes += match entry.metadata {
Some(Ok(ref m)) if !m.is_dir() => m.len(),
Some(Ok(_)) => 0,
Some(Err(_)) => {
num_errors += 1;
0
}
None => unreachable!(
"we ask for metadata, so we at least have Some(Err(..))). Issue in jwalk?"
),
};
}
Err(_) => num_errors += 1,
}
}

write_path(&mut out, &options, path, num_bytes, num_errors)?;
total += num_bytes;
res.num_errors += num_errors;
}
if num_roots > 1 && compute_total {
write_path(
&mut out,
&options,
Path::new("total"),
total,
res.num_errors,
)?;
}
Ok(res)
}

fn write_path(
out: &mut impl io::Write,
options: &WalkOptions,
path: impl AsRef<Path>,
num_bytes: u64,
num_errors: u64,
) -> Result<(), io::Error> {
writeln!(
out,
"{}\t{}{}",
options.format_bytes(num_bytes),
path.as_ref().display(),
if num_errors == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("\t<{} IO Error(s)>", num_errors))
}
)
}
45 changes: 45 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use jwalk::WalkDir;
use std::{fmt, path::Path};

pub enum ByteFormat {
Metric,
Binary,
Bytes,
}

pub struct WalkOptions {
pub threads: usize,
pub format: ByteFormat,
}

impl WalkOptions {
pub fn format_bytes(&self, b: u64) -> String {
use byte_unit::Byte;
use ByteFormat::*;
let binary = match self.format {
Bytes => return format!("{} b", b),
Binary => true,
Metric => false,
};
Byte::from_bytes(b as u128)
.get_appropriate_unit(binary)
.format(2)
}
pub fn iter_from_path(&self, path: &Path) -> WalkDir {
WalkDir::new(path)
.preload_metadata(true)
.skip_hidden(false)
.num_threads(self.threads)
}
}

#[derive(Default)]
pub struct WalkResult {
pub num_errors: u64,
}

impl fmt::Display for WalkResult {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "Encountered {} IO error(s)", self.num_errors)
}
}
124 changes: 2 additions & 122 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,128 +1,8 @@
extern crate failure;
extern crate jwalk;

mod common {
use jwalk::WalkDir;
use std::{fmt, path::Path};

pub enum ByteFormat {
Metric,
Binary,
Bytes,
}

pub struct WalkOptions {
pub threads: usize,
pub format: ByteFormat,
}

impl WalkOptions {
pub fn format_bytes(&self, b: u64) -> String {
use byte_unit::Byte;
use ByteFormat::*;
let binary = match self.format {
Bytes => return format!("{} b", b),
Binary => true,
Metric => false,
};
Byte::from_bytes(b as u128)
.get_appropriate_unit(binary)
.format(2)
}
pub fn iter_from_path(&self, path: &Path) -> WalkDir {
WalkDir::new(path)
.preload_metadata(true)
.skip_hidden(false)
.num_threads(self.threads)
}
}

#[derive(Default)]
pub struct WalkResult {
pub num_errors: u64,
}

impl fmt::Display for WalkResult {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "Encountered {} IO error(s)", self.num_errors)
}
}
}

mod aggregate {
use crate::{WalkOptions, WalkResult};
use failure::Error;
use std::borrow::Cow;
use std::{io, path::Path};

pub fn aggregate(
mut out: impl io::Write,
options: WalkOptions,
compute_total: bool,
paths: impl IntoIterator<Item = impl AsRef<Path>>,
) -> Result<WalkResult, Error> {
let mut res = WalkResult::default();
let mut total = 0;
let mut num_roots = 0;
for path in paths.into_iter() {
num_roots += 1;
let mut num_bytes = 0u64;
let mut num_errors = 0u64;
for entry in options.iter_from_path(path.as_ref()) {
match entry {
Ok(entry) => {
num_bytes += match entry.metadata {
Some(Ok(ref m)) if !m.is_dir() => m.len(),
Some(Ok(_)) => 0,
Some(Err(_)) => {
num_errors += 1;
0
}
None => unreachable!(
"we ask for metadata, so we at least have Some(Err(..))). Issue in jwalk?"
),
};
}
Err(_) => num_errors += 1,
}
}

write_path(&mut out, &options, path, num_bytes, num_errors)?;
total += num_bytes;
res.num_errors += num_errors;
}
if num_roots > 1 && compute_total {
write_path(
&mut out,
&options,
Path::new("total"),
total,
res.num_errors,
)?;
}
Ok(res)
}

fn write_path(
out: &mut impl io::Write,
options: &WalkOptions,
path: impl AsRef<Path>,
num_bytes: u64,
num_errors: u64,
) -> Result<(), io::Error> {
writeln!(
out,
"{}\t{}{}",
options.format_bytes(num_bytes),
path.as_ref().display(),
if num_errors == 0 {
Cow::Borrowed("")
} else {
Cow::Owned(format!("\t<{} IO Error(s)>", num_errors))
}
)
}
}
mod aggregate;
mod common;

pub use aggregate::aggregate;
pub use common::*;
62 changes: 1 addition & 61 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,67 +9,7 @@ use failure::Error;
use failure_tools::ok_or_exit;
use std::{io, path::PathBuf, process};

mod options {
use dua::ByteFormat as LibraryByteFormat;
use std::path::PathBuf;
use structopt::{clap::arg_enum, StructOpt};

arg_enum! {
#[derive(PartialEq, Debug)]
pub enum ByteFormat {
HumanMetric,
HumanBinary,
Bytes
}
}

impl From<ByteFormat> for LibraryByteFormat {
fn from(input: ByteFormat) -> Self {
match input {
ByteFormat::HumanMetric => LibraryByteFormat::Metric,
ByteFormat::HumanBinary => LibraryByteFormat::Binary,
ByteFormat::Bytes => LibraryByteFormat::Bytes,
}
}
}

#[derive(Debug, StructOpt)]
#[structopt(name = "dua", about = "A tool to learn about disk usage, fast!")]
pub struct Args {
#[structopt(subcommand)]
pub command: Option<Command>,

/// The amount of threads to use. Defaults to the amount of logical processors.
/// Set to 1 to use only a single thread.
#[structopt(short = "t", long = "threads")]
pub threads: Option<usize>,

/// The format with which to print byte counts.
/// HumanMetric - uses 1000 as base (default)
/// HumanBinary - uses 1024 as base
/// Bytes - plain bytes without any formatting
#[structopt(short = "f", long = "format")]
pub format: Option<ByteFormat>,

/// One or more input files. If unset, we will assume the current directory
#[structopt(parse(from_os_str))]
pub input: Vec<PathBuf>,
}

#[derive(Debug, StructOpt)]
pub enum Command {
/// Aggregrate the consumed space of one or more directories or files
#[structopt(name = "aggregate", alias = "a")]
Aggregate {
/// If set, no total column will be computed for multiple inputs
#[structopt(long = "no-total")]
no_total: bool,
/// One or more input files. If unset, we will assume the current directory
#[structopt(parse(from_os_str))]
input: Vec<PathBuf>,
},
}
}
mod options;

fn run() -> Result<(), Error> {
use options::Command::*;
Expand Down
59 changes: 59 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use dua::ByteFormat as LibraryByteFormat;
use std::path::PathBuf;
use structopt::{clap::arg_enum, StructOpt};

arg_enum! {
#[derive(PartialEq, Debug)]
pub enum ByteFormat {
HumanMetric,
HumanBinary,
Bytes
}
}

impl From<ByteFormat> for LibraryByteFormat {
fn from(input: ByteFormat) -> Self {
match input {
ByteFormat::HumanMetric => LibraryByteFormat::Metric,
ByteFormat::HumanBinary => LibraryByteFormat::Binary,
ByteFormat::Bytes => LibraryByteFormat::Bytes,
}
}
}

#[derive(Debug, StructOpt)]
#[structopt(name = "dua", about = "A tool to learn about disk usage, fast!")]
pub struct Args {
#[structopt(subcommand)]
pub command: Option<Command>,

/// The amount of threads to use. Defaults to the amount of logical processors.
/// Set to 1 to use only a single thread.
#[structopt(short = "t", long = "threads")]
pub threads: Option<usize>,

/// The format with which to print byte counts.
/// HumanMetric - uses 1000 as base (default)
/// HumanBinary - uses 1024 as base
/// Bytes - plain bytes without any formatting
#[structopt(short = "f", long = "format")]
pub format: Option<ByteFormat>,

/// One or more input files. If unset, we will assume the current directory
#[structopt(parse(from_os_str))]
pub input: Vec<PathBuf>,
}

#[derive(Debug, StructOpt)]
pub enum Command {
/// Aggregrate the consumed space of one or more directories or files
#[structopt(name = "aggregate", alias = "a")]
Aggregate {
/// If set, no total column will be computed for multiple inputs
#[structopt(long = "no-total")]
no_total: bool,
/// One or more input files. If unset, we will assume the current directory
#[structopt(parse(from_os_str))]
input: Vec<PathBuf>,
},
}

0 comments on commit 8b2ef49

Please sign in to comment.