@@ -106,6 +106,7 @@ enum NumberSystem {
106106 Decimal ,
107107 Octal ,
108108 Hexadecimal ,
109+ Binary ,
109110}
110111
111112impl < ' parser > Parser < ' parser > {
@@ -134,10 +135,11 @@ impl<'parser> Parser<'parser> {
134135 }
135136 /// Parse a size string into a number of bytes.
136137 ///
137- /// A size string comprises an integer and an optional unit. The unit
138- /// may be K, M, G, T, P, E, Z, Y, R or Q (powers of 1024), or KB, MB,
139- /// etc. (powers of 1000), or b which is 512.
140- /// Binary prefixes can be used, too: KiB=K, MiB=M, and so on.
138+ /// A size string comprises an integer and an optional unit. The integer
139+ /// may be in decimal, octal (0 prefix), hexadecimal (0x prefix), or
140+ /// binary (0b prefix) notation. The unit may be K, M, G, T, P, E, Z, Y,
141+ /// R or Q (powers of 1024), or KB, MB, etc. (powers of 1000), or b which
142+ /// is 512. Binary prefixes can be used, too: KiB=K, MiB=M, and so on.
141143 ///
142144 /// # Errors
143145 ///
@@ -159,6 +161,7 @@ impl<'parser> Parser<'parser> {
159161 /// assert_eq!(Ok(9 * 1000), parser.parse("9kB")); // kB is 1000
160162 /// assert_eq!(Ok(2 * 1024), parser.parse("2K")); // K is 1024
161163 /// assert_eq!(Ok(44251 * 1024), parser.parse("0xACDBK")); // 0xACDB is 44251 in decimal
164+ /// assert_eq!(Ok(44251 * 1024 * 1024), parser.parse("0b1010110011011011")); // 0b1010110011011011 is 44251 in decimal, default M
162165 /// ```
163166 pub fn parse ( & self , size : & str ) -> Result < u128 , ParseSizeError > {
164167 if size. is_empty ( ) {
@@ -176,6 +179,11 @@ impl<'parser> Parser<'parser> {
176179 . take ( 2 )
177180 . chain ( size. chars ( ) . skip ( 2 ) . take_while ( char:: is_ascii_hexdigit) )
178181 . collect ( ) ,
182+ NumberSystem :: Binary => size
183+ . chars ( )
184+ . take ( 2 )
185+ . chain ( size. chars ( ) . skip ( 2 ) . take_while ( |c| c. is_digit ( 2 ) ) )
186+ . collect ( ) ,
179187 _ => size. chars ( ) . take_while ( char:: is_ascii_digit) . collect ( ) ,
180188 } ;
181189 let mut unit: & str = & size[ numeric_string. len ( ) ..] ;
@@ -268,6 +276,10 @@ impl<'parser> Parser<'parser> {
268276 let trimmed_string = numeric_string. trim_start_matches ( "0x" ) ;
269277 Self :: parse_number ( trimmed_string, 16 , size) ?
270278 }
279+ NumberSystem :: Binary => {
280+ let trimmed_string = numeric_string. trim_start_matches ( "0b" ) ;
281+ Self :: parse_number ( trimmed_string, 2 , size) ?
282+ }
271283 } ;
272284
273285 number
@@ -328,6 +340,14 @@ impl<'parser> Parser<'parser> {
328340 return NumberSystem :: Hexadecimal ;
329341 }
330342
343+ // Binary prefix: "0b" followed by at least one binary digit (0 or 1)
344+ // Note: "0b" alone is treated as decimal 0 with suffix "b"
345+ if let Some ( prefix) = size. strip_prefix ( "0b" ) {
346+ if !prefix. is_empty ( ) {
347+ return NumberSystem :: Binary ;
348+ }
349+ }
350+
331351 let num_digits: usize = size
332352 . chars ( )
333353 . take_while ( char:: is_ascii_digit)
@@ -363,7 +383,9 @@ impl<'parser> Parser<'parser> {
363383/// assert_eq!(Ok(123), parse_size_u128("123"));
364384/// assert_eq!(Ok(9 * 1000), parse_size_u128("9kB")); // kB is 1000
365385/// assert_eq!(Ok(2 * 1024), parse_size_u128("2K")); // K is 1024
366- /// assert_eq!(Ok(44251 * 1024), parse_size_u128("0xACDBK"));
386+ /// assert_eq!(Ok(44251 * 1024), parse_size_u128("0xACDBK")); // hexadecimal
387+ /// assert_eq!(Ok(10), parse_size_u128("0b1010")); // binary
388+ /// assert_eq!(Ok(10 * 1024), parse_size_u128("0b1010K")); // binary with suffix
367389/// ```
368390pub fn parse_size_u128 ( size : & str ) -> Result < u128 , ParseSizeError > {
369391 Parser :: default ( ) . parse ( size)
@@ -564,6 +586,7 @@ mod tests {
564586 assert ! ( parse_size_u64( "1Y" ) . is_err( ) ) ;
565587 assert ! ( parse_size_u64( "1R" ) . is_err( ) ) ;
566588 assert ! ( parse_size_u64( "1Q" ) . is_err( ) ) ;
589+ assert ! ( parse_size_u64( "0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" ) . is_err( ) ) ;
567590
568591 assert ! ( variant_eq(
569592 & parse_size_u64( "1Z" ) . unwrap_err( ) ,
@@ -634,6 +657,7 @@ mod tests {
634657 #[ test]
635658 fn b_suffix ( ) {
636659 assert_eq ! ( Ok ( 3 * 512 ) , parse_size_u64( "3b" ) ) ; // b is 512
660+ assert_eq ! ( Ok ( 0 ) , parse_size_u64( "0b" ) ) ; // b should be used as a suffix in this case instead of signifying binary
637661 }
638662
639663 #[ test]
@@ -774,6 +798,12 @@ mod tests {
774798 assert_eq ! ( Ok ( 44251 * 1024 ) , parse_size_u128( "0xACDBK" ) ) ;
775799 }
776800
801+ #[ test]
802+ fn parse_binary_size ( ) {
803+ assert_eq ! ( Ok ( 44251 ) , parse_size_u64( "0b1010110011011011" ) ) ;
804+ assert_eq ! ( Ok ( 44251 * 1024 ) , parse_size_u64( "0b1010110011011011K" ) ) ;
805+ }
806+
777807 #[ test]
778808 #[ cfg( target_os = "linux" ) ]
779809 fn parse_percent ( ) {
0 commit comments