@@ -18,7 +18,7 @@ use gettextrs::{bind_textdomain_codeset, gettext, setlocale, textdomain, LocaleC
1818use plib:: PROJECT_NAME ;
1919#[ cfg( target_os = "macos" ) ]
2020use 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+
8288pub struct Field {
8389 caption : String ,
8490 width : usize ,
91+ typ : FieldType ,
8592}
8693
8794impl 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
208222impl 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