Skip to content

Commit 6841654

Browse files
authored
Merge pull request #293 from fox0/df--display
df: impl Display for Field
2 parents 02d0566 + 365b3f5 commit 6841654

File tree

1 file changed

+82
-67
lines changed

1 file changed

+82
-67
lines changed

fs/df.rs

Lines changed: 82 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleC
1818
use plib::PROJECT_NAME;
1919
#[cfg(target_os = "macos")]
2020
use std::ffi::CStr;
21-
use std::{cmp, ffi::CString, io};
21+
use std::{cmp, ffi::CString, fmt::Display, io};
2222

2323
#[derive(Parser)]
2424
#[command(version, about = gettext("df - report free storage space"))]
@@ -79,35 +79,41 @@ impl OutputMode {
7979
}
8080
}
8181

82+
pub enum FieldType {
83+
Str,
84+
Num,
85+
Pcent,
86+
}
87+
8288
pub struct Field {
8389
caption: String,
8490
width: usize,
91+
typ: FieldType,
8592
}
8693

8794
impl Field {
88-
pub fn new(caption: String, min_width: usize) -> Self {
95+
pub fn new(caption: String, min_width: usize, typ: FieldType) -> Self {
8996
let width = cmp::max(caption.len(), min_width);
90-
Self { caption, width }
91-
}
92-
93-
pub fn print_header(&self) {
94-
print!("{: <width$} ", self.caption, width = self.width);
95-
}
96-
97-
pub fn print_header_align_right(&self) {
98-
print!("{: >width$} ", self.caption, width = self.width);
99-
}
100-
101-
pub fn print_string(&self, value: &String) {
102-
print!("{: <width$} ", value, width = self.width);
97+
Self {
98+
caption,
99+
width,
100+
typ,
101+
}
103102
}
104103

105-
pub fn print_u64(&self, value: u64) {
106-
print!("{: >width$} ", value, width = self.width);
104+
pub fn format<T: Display>(&self, value: &T) -> String {
105+
match self.typ {
106+
FieldType::Str => format!("{value: <width$}", width = self.width),
107+
FieldType::Num => format!("{value: >width$}", width = self.width),
108+
FieldType::Pcent => format!("{value: >width$}", width = self.width - 1),
109+
}
107110
}
111+
}
108112

109-
pub fn print_percentage(&self, value: u32) {
110-
print!("{: >width$}% ", value, width = self.width - 1);
113+
/// Print header
114+
impl Display for Field {
115+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116+
write!(f, "{}", self.format(&self.caption))
111117
}
112118
}
113119

@@ -134,46 +140,54 @@ impl Fields {
134140
let size_caption = format!("{}-{}", mode.get_block_size(), gettext("blocks"));
135141
Self {
136142
mode,
137-
source: Field::new(gettext("Filesystem"), 14),
138-
size: Field::new(size_caption, 10),
139-
used: Field::new(gettext("Used"), 10),
140-
avail: Field::new(gettext("Available"), 10),
141-
pcent: Field::new(gettext("Capacity"), 5),
142-
target: Field::new(gettext("Mounted on"), 0),
143+
source: Field::new(gettext("Filesystem"), 14, FieldType::Str),
144+
size: Field::new(size_caption, 10, FieldType::Num),
145+
used: Field::new(gettext("Used"), 10, FieldType::Num),
146+
avail: Field::new(gettext("Available"), 10, FieldType::Num),
147+
pcent: Field::new(gettext("Capacity"), 5, FieldType::Pcent),
148+
target: Field::new(gettext("Mounted on"), 0, FieldType::Str),
143149
}
144150
}
151+
}
145152

146-
pub fn print_header(&self) {
147-
self.source.print_header();
148-
self.size.print_header_align_right();
149-
self.used.print_header_align_right();
150-
self.avail.print_header_align_right();
151-
self.pcent.print_header_align_right();
152-
self.target.print_header();
153-
println!();
153+
/// Print header
154+
impl Display for Fields {
155+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156+
write!(
157+
f,
158+
"{} {} {} {} {} {}",
159+
self.source, self.size, self.used, self.avail, self.pcent, self.target
160+
)
154161
}
162+
}
163+
164+
pub struct FieldsData<'a> {
165+
pub fields: &'a Fields,
166+
pub source: &'a String,
167+
pub size: u64,
168+
pub used: u64,
169+
pub avail: u64,
170+
pub pcent: u32,
171+
pub target: &'a String,
172+
}
155173

156-
fn print_row(
157-
&self,
158-
fsname: &String,
159-
total: u64,
160-
used: u64,
161-
avail: u64,
162-
percentage_used: u32,
163-
target: &String,
164-
) {
165-
// The remaining output with -P shall consist of one line of information
166-
// for each specified file system. These lines shall be formatted as follows:
167-
// "%s %d %d %d %d%% %s\n", <file system name>, <total space>,
168-
// <space used>, <space free>, <percentage used>,
169-
// <file system root>
170-
self.source.print_string(fsname);
171-
self.size.print_u64(total);
172-
self.used.print_u64(used);
173-
self.avail.print_u64(avail);
174-
self.pcent.print_percentage(percentage_used);
175-
self.target.print_string(target);
176-
println!();
174+
impl Display for FieldsData<'_> {
175+
// The remaining output with -P shall consist of one line of information
176+
// for each specified file system. These lines shall be formatted as follows:
177+
// "%s %d %d %d %d%% %s\n", <file system name>, <total space>,
178+
// <space used>, <space free>, <percentage used>,
179+
// <file system root>
180+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
181+
write!(
182+
f,
183+
"{} {} {} {} {}% {}",
184+
self.fields.source.format(self.source),
185+
self.fields.size.format(&self.size),
186+
self.fields.used.format(&self.used),
187+
self.fields.avail.format(&self.avail),
188+
self.fields.pcent.format(&self.pcent),
189+
self.fields.target.format(self.target)
190+
)
177191
}
178192
}
179193

@@ -206,11 +220,7 @@ struct Mount {
206220
}
207221

208222
impl Mount {
209-
fn print(&self, fields: &Fields) {
210-
if !self.masked {
211-
return;
212-
}
213-
223+
fn to_row<'a>(&'a self, fields: &'a Fields) -> FieldsData<'a> {
214224
let sf = self.cached_statfs;
215225

216226
let block_size = fields.mode.get_block_size();
@@ -227,14 +237,15 @@ impl Mount {
227237
let percentage_used = percentage_used * 100.0;
228238
let percentage_used = percentage_used.ceil() as u32;
229239

230-
fields.print_row(
231-
&self.devname,
232-
total,
240+
FieldsData {
241+
fields: &fields,
242+
source: &self.devname,
243+
size: total,
233244
used,
234245
avail,
235-
percentage_used,
236-
&self.dir,
237-
);
246+
pcent: percentage_used,
247+
target: &self.dir,
248+
}
238249
}
239250
}
240251

@@ -373,10 +384,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
373384

374385
let mode = OutputMode::new(args.kilo, args.portable);
375386
let fields = Fields::new(mode);
376-
fields.print_header();
387+
// Print header
388+
println!("{}", fields);
377389

378390
for mount in &info.mounts {
379-
mount.print(&fields);
391+
if mount.masked {
392+
let row = mount.to_row(&fields);
393+
println!("{}", row);
394+
}
380395
}
381396

382397
Ok(())

0 commit comments

Comments
 (0)