1
- // ported from https://github.com/niklasf/rust-btoi version 0.4.3
2
- // see https://github.com/Byron/gitoxide/issues/729#issuecomment-1941515655
1
+ /// A module with utilities to turn byte slices with decimal numbers back into their
2
+ /// binary representation.
3
+ ///
4
+ /// ### Credits
5
+ ///
6
+ /// This module was ported from <https://github.com/niklasf/rust-btoi> version 0.4.3
7
+ /// see <https://github.com/Byron/gitoxide/issues/729> for how it came to be in order
8
+ /// to save 2.2 seconds of per-core compile time by not compiling the `num-traits` crate
9
+ /// anymore.
10
+ ///
11
+ /// Licensed with compatible licenses [MIT] and [Apache]
12
+ ///
13
+ /// [MIT]: https://github.com/niklasf/rust-btoi/blob/master/LICENSE-MIT
14
+ /// [Apache]: https://github.com/niklasf/rust-btoi/blob/master/LICENSE-APACHE
3
15
4
16
/// An error that can occur when parsing an integer.
5
17
///
@@ -42,52 +54,6 @@ impl std::error::Error for ParseIntegerError {
42
54
self . desc ( )
43
55
}
44
56
}
45
- /// minimal subset of traits used by btoi_radix and btou_radix
46
- pub trait MinNumTraits : Sized + Copy {
47
- ///
48
- fn from_u32 ( n : u32 ) -> Option < Self > ;
49
- ///
50
- fn zero ( ) -> Self ;
51
- ///
52
- fn checked_mul ( self , v : Self ) -> Option < Self > ;
53
- ///
54
- fn checked_add ( self , v : Self ) -> Option < Self > ;
55
- ///
56
- fn checked_sub ( self , v : Self ) -> Option < Self > ;
57
- }
58
-
59
- macro_rules! min_num_traits {
60
- ( $t : ty, from_u32 => $from_u32 : expr) => {
61
- impl MinNumTraits for $t {
62
- fn from_u32( n: u32 ) -> Option <$t> {
63
- #[ allow( clippy:: redundant_closure_call) ]
64
- $from_u32( n)
65
- }
66
-
67
- fn zero( ) -> Self {
68
- 0
69
- }
70
-
71
- fn checked_mul( self , v: $t) -> Option <$t> {
72
- <$t>:: checked_mul( self , v)
73
- }
74
-
75
- fn checked_add( self , v: $t) -> Option <$t> {
76
- <$t>:: checked_add( self , v)
77
- }
78
-
79
- fn checked_sub( self , v: $t) -> Option <$t> {
80
- <$t>:: checked_sub( self , v)
81
- }
82
- }
83
- } ;
84
- }
85
-
86
- min_num_traits ! ( i32 , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
87
- min_num_traits ! ( i64 , from_u32 => |n: u32 | Some ( n. into( ) ) ) ;
88
- min_num_traits ! ( u64 , from_u32 => |n: u32 | Some ( n. into( ) ) ) ;
89
- min_num_traits ! ( u8 , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
90
- min_num_traits ! ( usize , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
91
57
92
58
/// Converts a byte slice to an integer. Signs are not allowed.
93
59
///
@@ -107,23 +73,14 @@ min_num_traits!(usize, from_u32 => |n: u32| n.try_into().ok());
107
73
/// # Examples
108
74
///
109
75
/// ```
110
- /// # use btoi::btou ;
111
- /// assert_eq!(Ok(12345), btou (b"12345"));
112
- /// assert!(btou ::<u8>(b"+1").is_err()); // only btoi allows signs
113
- /// assert!(btou ::<u8>(b"256").is_err()); // overflow
76
+ /// # use gix_utils:: btoi::to_unsigned ;
77
+ /// assert_eq!(Ok(12345), to_unsigned (b"12345"));
78
+ /// assert!(to_unsigned ::<u8>(b"+1").is_err()); // only btoi allows signs
79
+ /// assert!(to_unsigned ::<u8>(b"256").is_err()); // overflow
114
80
/// ```
115
- ///
116
- /// [`ParseIntegerError`]: struct.ParseIntegerError.html
117
81
#[ track_caller]
118
- pub fn btou < I : MinNumTraits > ( bytes : & [ u8 ] ) -> Result < I , ParseIntegerError > {
119
- btou_radix ( bytes, 10 )
120
- }
121
-
122
- #[ test]
123
- fn btou_assert ( ) {
124
- assert_eq ! ( Ok ( 12345 ) , btou( b"12345" ) ) ;
125
- assert ! ( btou:: <u8 >( b"+1" ) . is_err( ) ) ; // only btoi allows signs
126
- assert ! ( btou:: <u8 >( b"256" ) . is_err( ) ) ; // overflow
82
+ pub fn to_unsigned < I : MinNumTraits > ( bytes : & [ u8 ] ) -> Result < I , ParseIntegerError > {
83
+ to_unsigned_with_radix ( bytes, 10 )
127
84
}
128
85
129
86
/// Converts a byte slice in a given base to an integer. Signs are not allowed.
@@ -145,13 +102,11 @@ fn btou_assert() {
145
102
/// # Examples
146
103
///
147
104
/// ```
148
- /// # use btoi::btou_radix ;
149
- /// assert_eq!(Ok(255), btou_radix (b"ff", 16));
150
- /// assert_eq!(Ok(42), btou_radix (b"101010", 2));
105
+ /// # use gix_utils:: btoi::to_unsigned_with_radix ;
106
+ /// assert_eq!(Ok(255), to_unsigned_with_radix (b"ff", 16));
107
+ /// assert_eq!(Ok(42), to_unsigned_with_radix (b"101010", 2));
151
108
/// ```
152
- ///
153
- /// [`ParseIntegerError`]: struct.ParseIntegerError.html
154
- pub fn btou_radix < I : MinNumTraits > ( bytes : & [ u8 ] , radix : u32 ) -> Result < I , ParseIntegerError > {
109
+ pub fn to_unsigned_with_radix < I : MinNumTraits > ( bytes : & [ u8 ] , radix : u32 ) -> Result < I , ParseIntegerError > {
155
110
assert ! (
156
111
( 2 ..=36 ) . contains( & radix) ,
157
112
"radix must lie in the range 2..=36, found {radix}"
@@ -195,15 +150,9 @@ pub fn btou_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Result<I, ParseI
195
150
Ok ( result)
196
151
}
197
152
198
- #[ test]
199
- fn btou_radix_assert ( ) {
200
- assert_eq ! ( Ok ( 255 ) , btou_radix( b"ff" , 16 ) ) ;
201
- assert_eq ! ( Ok ( 42 ) , btou_radix( b"101010" , 2 ) ) ;
202
- }
203
-
204
153
/// Converts a byte slice to an integer.
205
154
///
206
- /// Like [`btou `], but numbers may optionally start with a sign (`-` or `+`).
155
+ /// Like [`to_unsigned `], but numbers may optionally start with a sign (`-` or `+`).
207
156
///
208
157
/// # Errors
209
158
///
@@ -222,38 +171,23 @@ fn btou_radix_assert() {
222
171
/// # Examples
223
172
///
224
173
/// ```
225
- /// # use btoi ::btoi;
226
- /// assert_eq!(Ok(123), btoi (b"123"));
227
- /// assert_eq!(Ok(123), btoi (b"+123"));
228
- /// assert_eq!(Ok(-123), btoi (b"-123"));
174
+ /// # use gix_utils ::btoi::to_signed ;
175
+ /// assert_eq!(Ok(123), to_signed (b"123"));
176
+ /// assert_eq!(Ok(123), to_signed (b"+123"));
177
+ /// assert_eq!(Ok(-123), to_signed (b"-123"));
229
178
///
230
- /// assert!(btoi ::<i16 >(b"123456789").is_err()); // overflow
231
- /// assert!(btoi ::<u32 >(b"-1").is_err()); // underflow
179
+ /// assert!(to_signed ::<u8 >(b"123456789").is_err()); // overflow
180
+ /// assert!(to_signed ::<u8 >(b"-1").is_err()); // underflow
232
181
///
233
- /// assert!(btoi ::<i32>(b" 42").is_err()); // leading space
182
+ /// assert!(to_signed ::<i32>(b" 42").is_err()); // leading space
234
183
/// ```
235
- ///
236
- /// [`btou`]: fn.btou.html
237
- /// [`ParseIntegerError`]: struct.ParseIntegerError.html
238
- pub fn btoi < I : MinNumTraits > ( bytes : & [ u8 ] ) -> Result < I , ParseIntegerError > {
239
- btoi_radix ( bytes, 10 )
240
- }
241
-
242
- #[ test]
243
- fn btoi_assert ( ) {
244
- assert_eq ! ( Ok ( 123 ) , btoi( b"123" ) ) ;
245
- assert_eq ! ( Ok ( 123 ) , btoi( b"+123" ) ) ;
246
- assert_eq ! ( Ok ( -123 ) , btoi( b"-123" ) ) ;
247
-
248
- assert ! ( btoi:: <u8 >( b"123456789" ) . is_err( ) ) ; // overflow
249
- assert ! ( btoi:: <u64 >( b"-1" ) . is_err( ) ) ; // underflow
250
-
251
- assert ! ( btoi:: <i32 >( b" 42" ) . is_err( ) ) ; // leading space
184
+ pub fn to_signed < I : MinNumTraits > ( bytes : & [ u8 ] ) -> Result < I , ParseIntegerError > {
185
+ to_signed_with_radix ( bytes, 10 )
252
186
}
253
187
254
188
/// Converts a byte slice in a given base to an integer.
255
189
///
256
- /// Like [`btou_radix `], but numbers may optionally start with a sign
190
+ /// Like [`to_unsigned_with_radix `], but numbers may optionally start with a sign
257
191
/// (`-` or `+`).
258
192
///
259
193
/// # Errors
@@ -275,15 +209,12 @@ fn btoi_assert() {
275
209
/// # Examples
276
210
///
277
211
/// ```
278
- /// # use btoi::btoi_radix ;
279
- /// assert_eq!(Ok(10), btoi_radix (b"a", 16));
280
- /// assert_eq!(Ok(10), btoi_radix (b"+a", 16));
281
- /// assert_eq!(Ok(-42), btoi_radix (b"-101010", 2));
212
+ /// # use gix_utils:: btoi::to_signed_with_radix ;
213
+ /// assert_eq!(Ok(10), to_signed_with_radix (b"a", 16));
214
+ /// assert_eq!(Ok(10), to_signed_with_radix (b"+a", 16));
215
+ /// assert_eq!(Ok(-42), to_signed_with_radix (b"-101010", 2));
282
216
/// ```
283
- ///
284
- /// [`btou_radix`]: fn.btou_radix.html
285
- /// [`ParseIntegerError`]: struct.ParseIntegerError.html
286
- fn btoi_radix < I : MinNumTraits > ( bytes : & [ u8 ] , radix : u32 ) -> Result < I , ParseIntegerError > {
217
+ pub fn to_signed_with_radix < I : MinNumTraits > ( bytes : & [ u8 ] , radix : u32 ) -> Result < I , ParseIntegerError > {
287
218
assert ! (
288
219
( 2 ..=36 ) . contains( & radix) ,
289
220
"radix must lie in the range 2..=36, found {radix}"
@@ -296,9 +227,9 @@ fn btoi_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Result<I, ParseInteg
296
227
}
297
228
298
229
let digits = match bytes[ 0 ] {
299
- b'+' => return btou_radix ( & bytes[ 1 ..] , radix) ,
230
+ b'+' => return to_unsigned_with_radix ( & bytes[ 1 ..] , radix) ,
300
231
b'-' => & bytes[ 1 ..] ,
301
- _ => return btou_radix ( bytes, radix) ,
232
+ _ => return to_unsigned_with_radix ( bytes, radix) ,
302
233
} ;
303
234
304
235
if digits. is_empty ( ) {
@@ -337,9 +268,49 @@ fn btoi_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Result<I, ParseInteg
337
268
Ok ( result)
338
269
}
339
270
340
- #[ test]
341
- fn btoi_radix_assert ( ) {
342
- assert_eq ! ( Ok ( 10 ) , btoi_radix( b"a" , 16 ) ) ;
343
- assert_eq ! ( Ok ( 10 ) , btoi_radix( b"+a" , 16 ) ) ;
344
- assert_eq ! ( Ok ( -42 ) , btoi_radix( b"-101010" , 2 ) ) ;
271
+ /// minimal subset of traits used by [`to_signed_with_radix`] and [`to_unsigned_with_radix`]
272
+ pub trait MinNumTraits : Sized + Copy {
273
+ ///
274
+ fn from_u32 ( n : u32 ) -> Option < Self > ;
275
+ ///
276
+ fn zero ( ) -> Self ;
277
+ ///
278
+ fn checked_mul ( self , v : Self ) -> Option < Self > ;
279
+ ///
280
+ fn checked_add ( self , v : Self ) -> Option < Self > ;
281
+ ///
282
+ fn checked_sub ( self , v : Self ) -> Option < Self > ;
283
+ }
284
+
285
+ macro_rules! min_num_traits {
286
+ ( $t : ty, from_u32 => $from_u32 : expr) => {
287
+ impl MinNumTraits for $t {
288
+ fn from_u32( n: u32 ) -> Option <$t> {
289
+ #[ allow( clippy:: redundant_closure_call) ]
290
+ $from_u32( n)
291
+ }
292
+
293
+ fn zero( ) -> Self {
294
+ 0
295
+ }
296
+
297
+ fn checked_mul( self , v: $t) -> Option <$t> {
298
+ <$t>:: checked_mul( self , v)
299
+ }
300
+
301
+ fn checked_add( self , v: $t) -> Option <$t> {
302
+ <$t>:: checked_add( self , v)
303
+ }
304
+
305
+ fn checked_sub( self , v: $t) -> Option <$t> {
306
+ <$t>:: checked_sub( self , v)
307
+ }
308
+ }
309
+ } ;
345
310
}
311
+
312
+ min_num_traits ! ( i32 , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
313
+ min_num_traits ! ( i64 , from_u32 => |n: u32 | Some ( n. into( ) ) ) ;
314
+ min_num_traits ! ( u64 , from_u32 => |n: u32 | Some ( n. into( ) ) ) ;
315
+ min_num_traits ! ( u8 , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
316
+ min_num_traits ! ( usize , from_u32 => |n: u32 | n. try_into( ) . ok( ) ) ;
0 commit comments