Skip to content

Commit

Permalink
line count
Browse files Browse the repository at this point in the history
  • Loading branch information
solidiquis committed May 22, 2023
1 parent a1abab5 commit 3a74846
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 72 deletions.
36 changes: 18 additions & 18 deletions src/disk_usage/file_size/byte.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use super::super::units::{BinPrefix, PrefixKind, SiPrefix, UnitPrefix};
use crate::context::Context;
use filesize::PathExt;
use std::{
convert::From,
fmt::{self, Display},
fs::Metadata,
path::Path,
Expand Down Expand Up @@ -38,6 +36,24 @@ impl Metric {
}
}

pub const fn init_empty_logical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
Self {
value: 0,
human_readable,
kind: MetricKind::Logical,
prefix_kind,
}
}

pub const fn init_empty_physical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
Self {
value: 0,
human_readable,
kind: MetricKind::Physical,
prefix_kind,
}
}

pub fn init_physical(
path: &Path,
metadata: &Metadata,
Expand All @@ -56,22 +72,6 @@ impl Metric {
}
}

impl From<&Context> for Metric {
fn from(ctx: &Context) -> Self {
let metric_kind = match ctx.disk_usage {
super::DiskUsage::Logical => MetricKind::Logical,
super::DiskUsage::Physical => MetricKind::Physical,
};

Self {
value: 0,
prefix_kind: ctx.unit,
human_readable: ctx.human,
kind: metric_kind,
}
}
}

impl Display for Metric {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let value = self.value as f64;
Expand Down
50 changes: 49 additions & 1 deletion src/disk_usage/file_size/line_count.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
use std::{
convert::{AsRef, From},
fmt::{self, Display},
fs,
path::Path,
};

#[derive(Default)]
pub struct Metric {
value: u64,
pub value: u64,
}

impl Metric {
pub fn init_lc<P: AsRef<Path>>(path: P) -> Option<Self> {
let data = fs::read(path.as_ref()).ok();

let Some(text) = data else {
return None;
};

let lines = text.into_iter().fold(0, |acc, item| {
if u32::from(item) == u32::from('\n') {
acc + 1
} else {
acc
}
});

u64::try_from(lines).map(|value| Self { value }).ok()
}
}

impl From<u64> for Metric {
fn from(value: u64) -> Self {
Self { value }
}
}

impl Display for Metric {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<u64 as Display>::fmt(&self.value, f)
}
}

#[test]
fn test_lc() {
let metric = Metric::init_lc("tests/data/nemesis.txt")
.expect("Expected 'tests/data/nemesis.txt' to exist");

assert_eq!(metric.value, 4);
}
15 changes: 12 additions & 3 deletions src/disk_usage/file_size/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use std::{convert::From, ops::AddAssign};
pub mod byte;
//pub mod block;
//pub mod word_count;
//pub mod line_count;
pub mod line_count;

pub enum FileSize {
//Block(block::Metric),
//WordCount(word_count::Metric),
//LineCount(line_count::Metric),
Line(line_count::Metric),
Byte(byte::Metric),
}

Expand All @@ -23,13 +23,17 @@ pub enum DiskUsage {
/// How much actual space on disk in bytes, taking into account sparse files and compression.
#[default]
Physical,

/// How many total lines a file contains
Line,
}

impl FileSize {
#[inline]
pub const fn value(&self) -> u64 {
match self {
Self::Byte(metric) => metric.value,
Self::Line(metric) => metric.value,
}
}
}
Expand All @@ -38,14 +42,19 @@ impl AddAssign<&Self> for FileSize {
fn add_assign(&mut self, rhs: &Self) {
match self {
Self::Byte(metric) => metric.value += rhs.value(),
Self::Line(metric) => metric.value += rhs.value(),
}
}
}

impl From<&Context> for FileSize {
fn from(ctx: &Context) -> Self {
match ctx.disk_usage {
DiskUsage::Logical | DiskUsage::Physical => Self::Byte(byte::Metric::from(ctx)),
DiskUsage::Logical => Self::Byte(byte::Metric::init_empty_logical(ctx.human, ctx.unit)),
DiskUsage::Physical => {
Self::Byte(byte::Metric::init_empty_physical(ctx.human, ctx.unit))
}
DiskUsage::Line => Self::Line(line_count::Metric::default()),
}
}
}
61 changes: 41 additions & 20 deletions src/render/grid/cell.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
context::Context,
disk_usage::{file_size::FileSize, units::PrefixKind},
disk_usage::{
file_size::{byte, line_count, FileSize},
units::PrefixKind,
},
render::theme,
styles::{self, PLACEHOLDER},
tree::node::Node,
Expand Down Expand Up @@ -107,24 +110,8 @@ impl<'a> Cell<'a> {
};

match file_size {
FileSize::Byte(metric) => {
let max_size_width = ctx.max_size_width;
let max_unit_width = ctx.max_size_unit_width;
let out = format!("{metric}");
let [size, unit]: [&str; 2] =
out.split(' ').collect::<Vec<&str>>().try_into().unwrap();

if ctx.no_color() {
write!(f, "{size:>max_size_width$} {unit:>max_unit_width$}")
} else {
let color = styles::get_du_theme().unwrap().get(unit).unwrap();

let out =
color.paint(format!("{size:>max_size_width$} {unit:>max_unit_width$}"));

write!(f, "{out}")
}
}
FileSize::Byte(metric) => Self::fmt_bytes(f, metric, ctx),
FileSize::Line(metric) => Self::fmt_line_count(f, metric, ctx),
}
}

Expand Down Expand Up @@ -244,7 +231,7 @@ impl<'a> Cell<'a> {
}

#[inline]
pub fn fmt_size_placeholder(f: &mut fmt::Formatter<'_>, ctx: &Context) -> fmt::Result {
fn fmt_size_placeholder(f: &mut fmt::Formatter<'_>, ctx: &Context) -> fmt::Result {
if ctx.suppress_size || ctx.max_size_width == 0 {
return write!(f, "");
}
Expand All @@ -265,6 +252,40 @@ impl<'a> Cell<'a> {

write!(f, "{placeholder:>placeholder_padding$}")
}

#[inline]
fn fmt_bytes(f: &mut fmt::Formatter<'_>, metric: &byte::Metric, ctx: &Context) -> fmt::Result {
let max_size_width = ctx.max_size_width;
let max_unit_width = ctx.max_size_unit_width;
let out = format!("{metric}");
let [size, unit]: [&str; 2] = out.split(' ').collect::<Vec<&str>>().try_into().unwrap();

if ctx.no_color() {
return write!(f, "{size:>max_size_width$} {unit:>max_unit_width$}");
}

let color = styles::get_du_theme().unwrap().get(unit).unwrap();

let out = color.paint(format!("{size:>max_size_width$} {unit:>max_unit_width$}"));

write!(f, "{out}")
}

#[inline]
fn fmt_line_count(
f: &mut fmt::Formatter<'_>,
metric: &line_count::Metric,
ctx: &Context,
) -> fmt::Result {
let max_size_width = ctx.max_size_width;

if ctx.no_color() {
return write!(f, "{metric:>max_size_width$}");
}
let color = styles::get_du_theme().unwrap().get("B").unwrap();

write!(f, "{}", color.paint(format!("{metric:>max_size_width$}")))
}
}

impl Display for Cell<'_> {
Expand Down
68 changes: 39 additions & 29 deletions src/tree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
context::{file, output::ColumnProperties, Context},
disk_usage::{
file_size::FileSize,
file_size::{DiskUsage, FileSize},
units::{BinPrefix, PrefixKind, SiPrefix},
},
fs::inode::Inode,
Expand Down Expand Up @@ -315,20 +315,25 @@ impl Tree {
col_props.max_size_width = file_size_cols;
}

let unit_len = match ctx.unit {
PrefixKind::Bin if ctx.human => match BinPrefix::from(file_size.value()) {
BinPrefix::Base => 1,
_ => 3,
},
PrefixKind::Si if ctx.human => match SiPrefix::from(file_size.value()) {
SiPrefix::Base => 1,
_ => 2,
},
_ => 1,
};

if unit_len > col_props.max_size_unit_width {
col_props.max_size_unit_width = unit_len;
match ctx.disk_usage {
DiskUsage::Logical | DiskUsage::Physical => {
let unit_len = match ctx.unit {
PrefixKind::Bin if ctx.human => match BinPrefix::from(file_size.value()) {
BinPrefix::Base => 1,
_ => 3,
},
PrefixKind::Si if ctx.human => match SiPrefix::from(file_size.value()) {
SiPrefix::Base => 1,
_ => 2,
},
_ => 1,
};

if unit_len > col_props.max_size_unit_width {
col_props.max_size_unit_width = unit_len;
}
}
DiskUsage::Line => (),
}
}

Expand Down Expand Up @@ -369,20 +374,25 @@ impl Tree {
col_props.max_size_width = file_size_cols;
}

let unit_len = match ctx.unit {
PrefixKind::Bin if ctx.human => match BinPrefix::from(file_size.value()) {
BinPrefix::Base => 1,
_ => 3,
},
PrefixKind::Si if ctx.human => match SiPrefix::from(file_size.value()) {
SiPrefix::Base => 1,
_ => 2,
},
_ => 1,
};

if unit_len > col_props.max_size_unit_width {
col_props.max_size_unit_width = unit_len;
match ctx.disk_usage {
DiskUsage::Logical | DiskUsage::Physical => {
let unit_len = match ctx.unit {
PrefixKind::Bin if ctx.human => match BinPrefix::from(file_size.value()) {
BinPrefix::Base => 1,
_ => 3,
},
PrefixKind::Si if ctx.human => match SiPrefix::from(file_size.value()) {
SiPrefix::Base => 1,
_ => 2,
},
_ => 1,
};

if unit_len > col_props.max_size_unit_width {
col_props.max_size_unit_width = unit_len;
}
}
_ => (),
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/tree/node/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
context::Context,
disk_usage::file_size::{byte, DiskUsage, FileSize},
disk_usage::file_size::{byte, line_count, DiskUsage, FileSize},
fs::inode::Inode,
icons,
styles::get_ls_colors,
Expand Down Expand Up @@ -245,6 +245,10 @@ impl TryFrom<(DirEntry, &Context)> for Node {
byte::Metric::init_physical(path, &metadata, ctx.unit, ctx.human);
Some(FileSize::Byte(metric))
}
DiskUsage::Line => {
let metric = line_count::Metric::init_lc(path);
metric.map(FileSize::Line)
}
}
} else {
None
Expand Down
24 changes: 24 additions & 0 deletions tests/line_count.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use indoc::indoc;

mod utils;

#[test]
fn line_count() {
assert_eq!(
utils::run_cmd(&["--disk-usage", "line", "tests/data"]),
indoc!(
"6 ┌─ cassildas_song.md
6 ┌─ the_yellow_king
1 ├─ nylarlathotep.txt
4 ├─ nemesis.txt
2 ├─ necronomicon.txt
1 │ ┌─ lipsum.txt
1 ├─ lipsum
10 │ ┌─ polaris.txt
10 ├─ dream_cycle
24 data
3 directories, 6 files"
)
)
}

0 comments on commit 3a74846

Please sign in to comment.