Skip to content

Commit c2bbc20

Browse files
authored
Merge pull request #174 from solidiquis/long-edit
support for user and group
2 parents e0a6300 + 2d8931e commit c2bbc20

File tree

19 files changed

+676
-208
lines changed

19 files changed

+676
-208
lines changed

Cargo.lock

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ chrono = "0.4.24"
2929
clap = { version = "4.1.1", features = ["derive"] }
3030
clap_complete = "4.1.1"
3131
dirs = "5.0"
32+
errno = "0.3.1"
3233
filesize = "0.2.0"
3334
ignore = "0.4.2"
3435
indextree = "4.6.0"
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::convert::From;
33

44
/// Utility struct to help store maximum column widths for attributes of each node. Each width is
55
/// measured as the number of columns of the tty's window.
6-
pub struct ColumnProperties {
6+
pub struct Properties {
77
pub max_size_width: usize,
88
pub max_size_unit_width: usize,
99

@@ -15,9 +15,15 @@ pub struct ColumnProperties {
1515

1616
#[cfg(unix)]
1717
pub max_block_width: usize,
18+
19+
#[cfg(unix)]
20+
pub max_owner_width: usize,
21+
22+
#[cfg(unix)]
23+
pub max_group_width: usize,
1824
}
1925

20-
impl From<&Context> for ColumnProperties {
26+
impl From<&Context> for Properties {
2127
fn from(ctx: &Context) -> Self {
2228
let unit_width = match ctx.unit {
2329
PrefixKind::Bin if ctx.human => 3,
@@ -34,6 +40,10 @@ impl From<&Context> for ColumnProperties {
3440
max_ino_width: 0,
3541
#[cfg(unix)]
3642
max_block_width: 0,
43+
#[cfg(unix)]
44+
max_owner_width: 0,
45+
#[cfg(unix)]
46+
max_group_width: 0,
3747
}
3848
}
3949
}

src/context/mod.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use ignore::{
77
overrides::{Override, OverrideBuilder},
88
DirEntry,
99
};
10-
use output::ColumnProperties;
1110
use regex::Regex;
1211
use std::{
1312
borrow::Borrow,
@@ -35,7 +34,7 @@ pub mod file;
3534
pub mod layout;
3635

3736
/// Utilities to print output.
38-
pub mod output;
37+
pub mod column;
3938

4039
/// Printing order kinds.
4140
pub mod sort;
@@ -87,6 +86,21 @@ pub struct Context {
8786
#[arg(short, long)]
8887
pub long: bool,
8988

89+
/// Show file's groups
90+
#[cfg(unix)]
91+
#[arg(long)]
92+
pub group: bool,
93+
94+
/// Show each file's ino
95+
#[cfg(unix)]
96+
#[arg(long)]
97+
pub ino: bool,
98+
99+
/// Show the total number of hardlinks to the underlying inode
100+
#[cfg(unix)]
101+
#[arg(long)]
102+
pub nlink: bool,
103+
90104
/// Show permissions in numeric octal format instead of symbolic
91105
#[cfg(unix)]
92106
#[arg(long, requires = "long")]
@@ -142,6 +156,10 @@ pub struct Context {
142156
#[arg(short, long, value_enum, default_value_t = PrefixKind::default())]
143157
pub unit: PrefixKind,
144158

159+
/// Which kind of layout to use when rendering the output
160+
#[arg(short = 'y', long, value_enum, default_value_t = layout::Type::default())]
161+
pub layout: layout::Type,
162+
145163
/// Show hidden files
146164
#[arg(short = '.', long)]
147165
pub hidden: bool,
@@ -158,10 +176,6 @@ pub struct Context {
158176
#[arg(long)]
159177
pub dirs_only: bool,
160178

161-
/// Which kind of layout to use when rendering the output
162-
#[arg(long, value_enum, default_value_t = layout::Type::default())]
163-
pub layout: layout::Type,
164-
165179
/// Don't read configuration file
166180
#[arg(long)]
167181
pub no_config: bool,
@@ -208,6 +222,16 @@ pub struct Context {
208222
#[cfg(unix)]
209223
pub max_block_width: usize,
210224

225+
/// Restricts column width of file owner for long view
226+
#[clap(skip = usize::default())]
227+
#[cfg(unix)]
228+
pub max_owner_width: usize,
229+
230+
/// Restricts column width of file group for long view
231+
#[clap(skip = usize::default())]
232+
#[cfg(unix)]
233+
pub max_group_width: usize,
234+
211235
/// Width of the terminal emulator's window
212236
#[clap(skip)]
213237
pub window_width: Option<usize>,
@@ -486,12 +510,14 @@ impl Context {
486510
}
487511

488512
/// Update column width properties.
489-
pub fn update_column_properties(&mut self, col_props: &ColumnProperties) {
513+
pub fn update_column_properties(&mut self, col_props: &column::Properties) {
490514
self.max_size_width = col_props.max_size_width;
491515
self.max_size_unit_width = col_props.max_size_unit_width;
492516

493517
#[cfg(unix)]
494518
{
519+
self.max_owner_width = col_props.max_owner_width;
520+
self.max_group_width = col_props.max_group_width;
495521
self.max_nlink_width = col_props.max_nlink_width;
496522
self.max_block_width = col_props.max_block_width;
497523
self.max_ino_width = col_props.max_ino_width;

src/disk_usage/file_size/byte.rs

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::super::units::{BinPrefix, PrefixKind, SiPrefix, UnitPrefix};
22
use filesize::PathExt;
33
use std::{
4+
cell::{Ref, RefCell},
45
fmt::{self, Display},
56
fs::Metadata,
67
path::Path,
@@ -14,6 +15,11 @@ pub struct Metric {
1415
#[allow(dead_code)]
1516
kind: MetricKind,
1617
prefix_kind: PrefixKind,
18+
19+
/// To prevent allocating the same string twice. We allocate the first time
20+
/// in [`crate::tree::update_column_properties`] in order to compute the max column width for
21+
/// human-readable size and the second time during the actual render.
22+
cached_display: RefCell<String>,
1723
}
1824

1925
/// Represents the appropriate method in which to compute bytes. `Logical` represent the total amount
@@ -39,26 +45,29 @@ impl Metric {
3945
human_readable,
4046
kind,
4147
prefix_kind,
48+
cached_display: RefCell::default(),
4249
}
4350
}
4451

4552
/// Initializes an empty [Metric] used to represent the total amount of bytes of a file.
46-
pub const fn init_empty_logical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
53+
pub fn init_empty_logical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
4754
Self {
4855
value: 0,
4956
human_readable,
5057
kind: MetricKind::Logical,
5158
prefix_kind,
59+
cached_display: RefCell::default(),
5260
}
5361
}
5462

5563
/// Initializes an empty [Metric] used to represent the total disk space of a file in bytes.
56-
pub const fn init_empty_physical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
64+
pub fn init_empty_physical(human_readable: bool, prefix_kind: PrefixKind) -> Self {
5765
Self {
5866
value: 0,
5967
human_readable,
6068
kind: MetricKind::Physical,
6169
prefix_kind,
70+
cached_display: RefCell::default(),
6271
}
6372
}
6473

@@ -77,46 +86,66 @@ impl Metric {
7786
human_readable,
7887
kind,
7988
prefix_kind,
89+
cached_display: RefCell::default(),
8090
}
8191
}
92+
93+
/// Returns an immutable borrow of the `cached_display`.
94+
pub fn cached_display(&self) -> Ref<'_, String> {
95+
self.cached_display.borrow()
96+
}
8297
}
8398

8499
impl Display for Metric {
85100
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86-
let value = self.value as f64;
101+
{
102+
let cached_display = self.cached_display();
87103

88-
match self.prefix_kind {
89-
PrefixKind::Si => {
90-
if !self.human_readable {
91-
return write!(f, "{} {}", self.value, SiPrefix::Base);
92-
}
104+
if cached_display.len() > 0 {
105+
return write!(f, "{cached_display}");
106+
}
107+
}
93108

94-
let unit = SiPrefix::from(self.value);
109+
let value = self.value as f64;
95110

96-
if matches!(unit, SiPrefix::Base) {
97-
write!(f, "{} {unit}", self.value)
111+
let display = match self.prefix_kind {
112+
PrefixKind::Si => {
113+
if self.human_readable {
114+
let unit = SiPrefix::from(self.value);
115+
116+
if matches!(unit, SiPrefix::Base) {
117+
format!("{} {unit}", self.value)
118+
} else {
119+
let base_value = unit.base_value();
120+
let size = value / (base_value as f64);
121+
format!("{size:.1} {unit}")
122+
}
98123
} else {
99-
let base_value = unit.base_value();
100-
let size = value / (base_value as f64);
101-
write!(f, "{size:.2} {unit}")
124+
format!("{} {}", self.value, SiPrefix::Base)
102125
}
103126
}
104127
PrefixKind::Bin => {
105-
if !self.human_readable {
106-
return write!(f, "{} {}", self.value, BinPrefix::Base);
107-
}
108-
109-
let unit = BinPrefix::from(self.value);
110-
111-
if matches!(unit, BinPrefix::Base) {
112-
write!(f, "{} {unit}", self.value)
128+
if self.human_readable {
129+
let unit = BinPrefix::from(self.value);
130+
131+
if matches!(unit, BinPrefix::Base) {
132+
format!("{} {unit}", self.value)
133+
} else {
134+
let base_value = unit.base_value();
135+
let size = value / (base_value as f64);
136+
format!("{size:.1} {unit}")
137+
}
113138
} else {
114-
let base_value = unit.base_value();
115-
let size = value / (base_value as f64);
116-
write!(f, "{size:.2} {unit}")
139+
format!("{} {}", self.value, BinPrefix::Base)
117140
}
118141
}
119-
}
142+
};
143+
144+
write!(f, "{display}")?;
145+
146+
self.cached_display.replace(display);
147+
148+
Ok(())
120149
}
121150
}
122151

@@ -127,6 +156,7 @@ fn test_metric() {
127156
kind: MetricKind::Logical,
128157
human_readable: false,
129158
prefix_kind: PrefixKind::Bin,
159+
cached_display: RefCell::<String>::default(),
130160
};
131161
assert_eq!(format!("{}", metric), "100 B");
132162

@@ -135,14 +165,16 @@ fn test_metric() {
135165
kind: MetricKind::Logical,
136166
human_readable: true,
137167
prefix_kind: PrefixKind::Si,
168+
cached_display: RefCell::<String>::default(),
138169
};
139-
assert_eq!(format!("{}", metric), "1.00 KB");
170+
assert_eq!(format!("{}", metric), "1.0 KB");
140171

141172
let metric = Metric {
142173
value: 1000,
143174
kind: MetricKind::Logical,
144175
human_readable: true,
145176
prefix_kind: PrefixKind::Bin,
177+
cached_display: RefCell::<String>::default(),
146178
};
147179
assert_eq!(format!("{}", metric), "1000 B");
148180

@@ -151,22 +183,25 @@ fn test_metric() {
151183
kind: MetricKind::Logical,
152184
human_readable: true,
153185
prefix_kind: PrefixKind::Bin,
186+
cached_display: RefCell::<String>::default(),
154187
};
155-
assert_eq!(format!("{}", metric), "1.00 KiB");
188+
assert_eq!(format!("{}", metric), "1.0 KiB");
156189

157190
let metric = Metric {
158191
value: 2_u64.pow(20),
159192
kind: MetricKind::Logical,
160193
human_readable: true,
161194
prefix_kind: PrefixKind::Bin,
195+
cached_display: RefCell::<String>::default(),
162196
};
163-
assert_eq!(format!("{}", metric), "1.00 MiB");
197+
assert_eq!(format!("{}", metric), "1.0 MiB");
164198

165199
let metric = Metric {
166200
value: 123454,
167201
kind: MetricKind::Logical,
168202
human_readable: false,
169203
prefix_kind: PrefixKind::Bin,
204+
cached_display: RefCell::<String>::default(),
170205
};
171206
assert_eq!(format!("{}", metric), "123454 B");
172207
}

0 commit comments

Comments
 (0)