@@ -103,6 +103,65 @@ pub fn pib<V: Into<u64>>(size: V) -> u64 {
103103 size. into ( ) * PIB
104104}
105105
106+ /// 32 * 1024 Byte = 32 KiB
107+ pub struct IEC ;
108+
109+ /// 32 * 1000 Byte = 32 KB
110+ pub struct SI ;
111+
112+ /// 32 * 1024 Byte = 32K
113+ pub struct Sort ;
114+
115+ fn humanize ( bytes : u64 , si : bool , prefix : & str , suffix : & str ) -> String {
116+ let unit = if si { KB } else { KIB } ;
117+ let unit_base = if si { LN_KB } else { LN_KIB } ;
118+ let unit_prefix = if si {
119+ UNITS_SI . as_bytes ( )
120+ } else {
121+ UNITS . as_bytes ( )
122+ } ;
123+
124+ if bytes < unit {
125+ format ! ( "{}{}B" , bytes, prefix)
126+ } else {
127+ let size = bytes as f64 ;
128+ let exp = match ( size. ln ( ) / unit_base) as usize {
129+ e if e == 0 => 1 ,
130+ e => e,
131+ } ;
132+
133+ format ! (
134+ "{:.1}{}{}{}" ,
135+ ( size / unit. pow( exp as u32 ) as f64 ) ,
136+ prefix,
137+ unit_prefix[ exp - 1 ] as char ,
138+ suffix
139+ )
140+ }
141+ }
142+
143+ pub trait ByteFormatter {
144+ fn humanize ( & self , bytes : u64 ) -> String ;
145+ }
146+
147+ impl ByteFormatter for IEC {
148+ fn humanize ( & self , bytes : u64 ) -> String {
149+ humanize ( bytes, false , " " , "iB" )
150+ }
151+ }
152+
153+ impl ByteFormatter for SI {
154+ fn humanize ( & self , bytes : u64 ) -> String {
155+ humanize ( bytes, true , " " , "B" )
156+ }
157+ }
158+
159+ impl ByteFormatter for Sort {
160+ fn humanize ( & self , bytes : u64 ) -> String {
161+ humanize ( bytes, false , "" , "" )
162+ }
163+ }
164+
106165/// Byte size representation
107166#[ derive( Copy , Clone , PartialEq , PartialOrd , Eq , Ord , Default ) ]
108167#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -169,43 +228,46 @@ impl ByteSize {
169228 self . 0
170229 }
171230
231+ #[ deprecated( since="1.1.0" , note="use `bs.humanize(SI|IEC)`" ) ]
172232 #[ inline( always) ]
173233 pub fn to_string_as ( & self , si_unit : bool ) -> String {
174- to_string ( self . 0 , si_unit)
234+ if si_unit {
235+ self . humanize ( SI )
236+ } else {
237+ self . humanize ( IEC )
238+ }
239+ }
240+
241+ /// Returns humanized String representation.
242+ ///
243+ /// ## Examples
244+ ///
245+ /// ```
246+ /// # extern crate bytesize;
247+ /// # use bytesize::*;
248+ /// assert_eq!("1.0 KiB", ByteSize::b(1024).humanize(IEC));
249+ /// assert_eq!("1.0 kB", ByteSize::b(1000).humanize(SI));
250+ /// ```
251+ #[ inline( always) ]
252+ pub fn humanize < F > ( & self , fmt : F ) -> String
253+ where F : ByteFormatter
254+ {
255+ fmt. humanize ( self . 0 )
175256 }
176257}
177258
259+ #[ deprecated( since="1.1.0" , note="use `ByteSize::b(bytes).humanize(SI|IEC)`" ) ]
178260pub fn to_string ( bytes : u64 , si_prefix : bool ) -> String {
179- let unit = if si_prefix { KIB } else { KB } ;
180- let unit_base = if si_prefix { LN_KIB } else { LN_KB } ;
181- let unit_prefix = if si_prefix {
182- UNITS_SI . as_bytes ( )
261+ if si_prefix {
262+ humanize ( bytes, si_prefix, " " , "B" )
183263 } else {
184- UNITS . as_bytes ( )
185- } ;
186- let unit_suffix = if si_prefix { "iB" } else { "B" } ;
187-
188- if bytes < unit {
189- format ! ( "{} B" , bytes)
190- } else {
191- let size = bytes as f64 ;
192- let exp = match ( size. ln ( ) / unit_base) as usize {
193- e if e == 0 => 1 ,
194- e => e,
195- } ;
196-
197- format ! (
198- "{:.1} {}{}" ,
199- ( size / unit. pow( exp as u32 ) as f64 ) ,
200- unit_prefix[ exp - 1 ] as char ,
201- unit_suffix
202- )
264+ humanize ( bytes, si_prefix, " " , "iB" )
203265 }
204266}
205267
206268impl Display for ByteSize {
207269 fn fmt ( & self , f : & mut Formatter ) -> Result {
208- write ! ( f, "{}" , to_string ( self . 0 , false ) )
270+ write ! ( f, "{}" , self . humanize ( SI ) )
209271 }
210272}
211273
@@ -310,47 +372,57 @@ mod tests {
310372 #[ test]
311373 fn test_display ( ) {
312374 assert_display ( "215 B" , ByteSize :: b ( 215 ) ) ;
313- assert_display ( "1.0 KB " , ByteSize :: kb ( 1 ) ) ;
314- assert_display ( "301.0 KB " , ByteSize :: kb ( 301 ) ) ;
375+ assert_display ( "1.0 kB " , ByteSize :: kb ( 1 ) ) ;
376+ assert_display ( "301.0 kB " , ByteSize :: kb ( 301 ) ) ;
315377 assert_display ( "419.0 MB" , ByteSize :: mb ( 419 ) ) ;
316378 assert_display ( "518.0 GB" , ByteSize :: gb ( 518 ) ) ;
317379 assert_display ( "815.0 TB" , ByteSize :: tb ( 815 ) ) ;
318380 assert_display ( "609.0 PB" , ByteSize :: pb ( 609 ) ) ;
319381 }
320382
321- fn assert_to_string ( expected : & str , b : ByteSize , si : bool ) {
322- assert_eq ! ( expected. to_string( ) , b. to_string_as( si) ) ;
383+ fn assert_humanize < F > ( expected : & str , b : ByteSize , fmt : F )
384+ where F : ByteFormatter
385+ {
386+ assert_eq ! ( expected. to_string( ) , b. humanize( fmt) ) ;
323387 }
324388
325389 #[ test]
326- fn test_to_string_as ( ) {
327- assert_to_string ( "215 B" , ByteSize :: b ( 215 ) , true ) ;
328- assert_to_string ( "215 B" , ByteSize :: b ( 215 ) , false ) ;
390+ fn test_humanize ( ) {
391+ assert_humanize ( "215 B" , ByteSize :: b ( 215 ) , IEC ) ;
392+ assert_humanize ( "215 B" , ByteSize :: b ( 215 ) , SI ) ;
329393
330- assert_to_string ( "1.0 kiB" , ByteSize :: kib ( 1 ) , true ) ;
331- assert_to_string ( "1.0 KB" , ByteSize :: kib ( 1 ) , false ) ;
394+ assert_humanize ( "1.0 KiB" , ByteSize :: kib ( 1 ) , IEC ) ;
395+ assert_humanize ( "1.0 kB" , ByteSize :: kib ( 1 ) , SI ) ;
396+ assert_humanize ( "1.0K" , ByteSize :: kib ( 1 ) , Sort ) ;
332397
333- assert_to_string ( "293.9 kiB" , ByteSize :: kb ( 301 ) , true ) ;
334- assert_to_string ( "301.0 KB" , ByteSize :: kb ( 301 ) , false ) ;
398+ assert_humanize ( "293.9 KiB" , ByteSize :: kb ( 301 ) , IEC ) ;
399+ assert_humanize ( "301.0 kB" , ByteSize :: kb ( 301 ) , SI ) ;
400+ assert_humanize ( "293.9K" , ByteSize :: kb ( 301 ) , Sort ) ;
335401
336- assert_to_string ( "1.0 MiB" , ByteSize :: mib ( 1 ) , true ) ;
337- assert_to_string ( "1048.6 KB" , ByteSize :: mib ( 1 ) , false ) ;
402+ assert_humanize ( "1.0 MiB" , ByteSize :: mib ( 1 ) , IEC ) ;
403+ assert_humanize ( "1048.6 kB" , ByteSize :: mib ( 1 ) , SI ) ;
404+ assert_humanize ( "1.0M" , ByteSize :: mib ( 1 ) , Sort ) ;
338405
339406 // a bug case: https://github.com/flang-project/bytesize/issues/8
340- assert_to_string ( "1.9 GiB" , ByteSize :: mib ( 1907 ) , true ) ;
341- assert_to_string ( "2.0 GB" , ByteSize :: mib ( 1908 ) , false ) ;
407+ assert_humanize ( "1.9 GiB" , ByteSize :: mib ( 1907 ) , IEC ) ;
408+ assert_humanize ( "2.0 GB" , ByteSize :: mib ( 1908 ) , SI ) ;
409+ assert_humanize ( "1.9G" , ByteSize :: mib ( 1907 ) , Sort ) ;
342410
343- assert_to_string ( "399.6 MiB" , ByteSize :: mb ( 419 ) , true ) ;
344- assert_to_string ( "419.0 MB" , ByteSize :: mb ( 419 ) , false ) ;
411+ assert_humanize ( "399.6 MiB" , ByteSize :: mb ( 419 ) , IEC ) ;
412+ assert_humanize ( "419.0 MB" , ByteSize :: mb ( 419 ) , SI ) ;
413+ assert_humanize ( "399.6M" , ByteSize :: mb ( 419 ) , Sort ) ;
345414
346- assert_to_string ( "482.4 GiB" , ByteSize :: gb ( 518 ) , true ) ;
347- assert_to_string ( "518.0 GB" , ByteSize :: gb ( 518 ) , false ) ;
415+ assert_humanize ( "482.4 GiB" , ByteSize :: gb ( 518 ) , IEC ) ;
416+ assert_humanize ( "518.0 GB" , ByteSize :: gb ( 518 ) , SI ) ;
417+ assert_humanize ( "482.4G" , ByteSize :: gb ( 518 ) , Sort ) ;
348418
349- assert_to_string ( "741.2 TiB" , ByteSize :: tb ( 815 ) , true ) ;
350- assert_to_string ( "815.0 TB" , ByteSize :: tb ( 815 ) , false ) ;
419+ assert_humanize ( "741.2 TiB" , ByteSize :: tb ( 815 ) , IEC ) ;
420+ assert_humanize ( "815.0 TB" , ByteSize :: tb ( 815 ) , SI ) ;
421+ assert_humanize ( "741.2T" , ByteSize :: tb ( 815 ) , Sort ) ;
351422
352- assert_to_string ( "540.9 PiB" , ByteSize :: pb ( 609 ) , true ) ;
353- assert_to_string ( "609.0 PB" , ByteSize :: pb ( 609 ) , false ) ;
423+ assert_humanize ( "540.9 PiB" , ByteSize :: pb ( 609 ) , IEC ) ;
424+ assert_humanize ( "609.0 PB" , ByteSize :: pb ( 609 ) , SI ) ;
425+ assert_humanize ( "540.9P" , ByteSize :: pb ( 609 ) , Sort ) ;
354426 }
355427
356428 #[ test]
@@ -360,6 +432,6 @@ mod tests {
360432
361433 #[ test]
362434 fn test_to_string ( ) {
363- assert_to_string ( "609.0 PB" , ByteSize :: pb ( 609 ) , false ) ;
435+ assert_humanize ( "609.0 PB" , ByteSize :: pb ( 609 ) , SI ) ;
364436 }
365437}
0 commit comments