Skip to content

Commit 0993978

Browse files
authored
Make Integer be Binary, LowerHex and UpperHex (#792)
As per the title, but also add support for the "alternate" formatting flag for Binary, LowerHex and UpperHex. And tests.
1 parent dca28fb commit 0993978

File tree

6 files changed

+163
-8
lines changed

6 files changed

+163
-8
lines changed

CHANGELOG.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
- `?Sized` to all RngCore bounds ([#760])
1010

1111
### Changed
12-
- Make `as_limbs_mut` const ([#757])
12+
- Make `as_limbs_mut` const ([#757])
13+
- Make `Integer` be fmt::Binary, LowerHex and UpperHex ([#792])
1314

1415
[#757]: https://github.com/RustCrypto/crypto-bigint/pull/757
1516
[#760]: https://github.com/RustCrypto/crypto-bigint/pull/760
17+
[#792]:https://github.com/RustCrypto/crypto-bigint/pull/792
1618

1719
## 0.6.0 (2025-01-22)
1820
### Added
@@ -596,7 +598,7 @@ NOTE: this release was yanked due to [#82].
596598

597599
## 0.2.7 (2021-09-12)
598600
### Added
599-
- `UInt::shl_vartime`
601+
- `UInt::shl_vartime`
600602

601603
### Fixed
602604
- `add_mod` overflow handling

src/int.rs

+30
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,36 @@ mod tests {
349349
assert_eq!(hex, n.to_string());
350350
}
351351

352+
#[cfg(feature = "alloc")]
353+
#[test]
354+
fn fmt_lower_hex() {
355+
let n = I128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
356+
assert_eq!(format!("{n:x}"), "aaaaaaaabbbbbbbbccccccccdddddddd");
357+
assert_eq!(format!("{n:#x}"), "0xaaaaaaaabbbbbbbbccccccccdddddddd");
358+
}
359+
360+
#[cfg(feature = "alloc")]
361+
#[test]
362+
fn fmt_upper_hex() {
363+
let n = I128::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd");
364+
assert_eq!(format!("{n:X}"), "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
365+
assert_eq!(format!("{n:#X}"), "0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
366+
}
367+
368+
#[cfg(feature = "alloc")]
369+
#[test]
370+
fn fmt_binary() {
371+
let n = I128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
372+
assert_eq!(
373+
format!("{n:b}"),
374+
"10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
375+
);
376+
assert_eq!(
377+
format!("{n:#b}"),
378+
"0b10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
379+
);
380+
}
381+
352382
#[test]
353383
fn conditional_select() {
354384
let a = I128::from_be_hex("00002222444466668888AAAACCCCEEEE");

src/limb.rs

+10
Original file line numberDiff line numberDiff line change
@@ -160,20 +160,30 @@ impl fmt::Display for Limb {
160160
impl fmt::Binary for Limb {
161161
#[inline]
162162
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163+
if f.alternate() {
164+
write!(f, "0b")?;
165+
}
166+
163167
write!(f, "{:0width$b}", &self.0, width = Self::BITS as usize)
164168
}
165169
}
166170

167171
impl fmt::LowerHex for Limb {
168172
#[inline]
169173
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174+
if f.alternate() {
175+
write!(f, "0x")?;
176+
}
170177
write!(f, "{:0width$x}", &self.0, width = Self::BYTES * 2)
171178
}
172179
}
173180

174181
impl fmt::UpperHex for Limb {
175182
#[inline]
176183
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184+
if f.alternate() {
185+
write!(f, "0x")?;
186+
}
177187
write!(f, "{:0width$X}", &self.0, width = Self::BYTES * 2)
178188
}
179189
}

src/traits.rs

+3
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub trait Integer:
116116
+ for<'a> DivAssign<&'a NonZero<Self>>
117117
+ DivRemLimb
118118
+ Eq
119+
+ fmt::LowerHex
120+
+ fmt::UpperHex
121+
+ fmt::Binary
119122
+ From<u8>
120123
+ From<u16>
121124
+ From<u32>

src/uint.rs

+76-3
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,12 @@ impl<const LIMBS: usize> fmt::Debug for Uint<LIMBS> {
307307

308308
impl<const LIMBS: usize> fmt::Binary for Uint<LIMBS> {
309309
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310+
if f.alternate() {
311+
write!(f, "0b")?;
312+
}
313+
310314
for limb in self.limbs.iter().rev() {
311-
fmt::Binary::fmt(limb, f)?;
315+
write!(f, "{:0width$b}", &limb.0, width = Limb::BITS as usize)?;
312316
}
313317
Ok(())
314318
}
@@ -322,17 +326,23 @@ impl<const LIMBS: usize> fmt::Display for Uint<LIMBS> {
322326

323327
impl<const LIMBS: usize> fmt::LowerHex for Uint<LIMBS> {
324328
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329+
if f.alternate() {
330+
write!(f, "0x")?;
331+
}
325332
for limb in self.limbs.iter().rev() {
326-
fmt::LowerHex::fmt(limb, f)?;
333+
write!(f, "{:0width$x}", &limb.0, width = Limb::BYTES * 2)?;
327334
}
328335
Ok(())
329336
}
330337
}
331338

332339
impl<const LIMBS: usize> fmt::UpperHex for Uint<LIMBS> {
333340
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341+
if f.alternate() {
342+
write!(f, "0x")?;
343+
}
334344
for limb in self.limbs.iter().rev() {
335-
fmt::UpperHex::fmt(limb, f)?;
345+
write!(f, "{:0width$X}", &limb.0, width = Limb::BYTES * 2)?;
336346
}
337347
Ok(())
338348
}
@@ -523,6 +533,69 @@ mod tests {
523533
assert_eq!(hex, n.to_string());
524534
}
525535

536+
#[cfg(feature = "alloc")]
537+
#[test]
538+
fn fmt_lower_hex() {
539+
let n = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
540+
assert_eq!(format!("{n:x}"), "aaaaaaaabbbbbbbbccccccccdddddddd");
541+
assert_eq!(format!("{n:#x}"), "0xaaaaaaaabbbbbbbbccccccccdddddddd");
542+
}
543+
544+
#[cfg(feature = "alloc")]
545+
#[test]
546+
fn fmt_lower_hex_from_trait() {
547+
fn format_int<T: crate::Integer>(n: T) -> alloc::string::String {
548+
format!("{n:x}")
549+
}
550+
let n = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
551+
assert_eq!(format_int(n), "aaaaaaaabbbbbbbbccccccccdddddddd");
552+
}
553+
554+
#[cfg(feature = "alloc")]
555+
#[test]
556+
fn fmt_upper_hex() {
557+
let n = U128::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd");
558+
assert_eq!(format!("{n:X}"), "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
559+
assert_eq!(format!("{n:#X}"), "0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
560+
}
561+
562+
#[cfg(feature = "alloc")]
563+
#[test]
564+
fn fmt_upper_hex_from_trait() {
565+
fn format_int<T: crate::Integer>(n: T) -> alloc::string::String {
566+
format!("{n:X}")
567+
}
568+
let n = U128::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd");
569+
assert_eq!(format_int(n), "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
570+
}
571+
572+
#[cfg(feature = "alloc")]
573+
#[test]
574+
fn fmt_binary() {
575+
let n = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
576+
assert_eq!(
577+
format!("{n:b}"),
578+
"10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
579+
);
580+
assert_eq!(
581+
format!("{n:#b}"),
582+
"0b10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
583+
);
584+
}
585+
586+
#[cfg(feature = "alloc")]
587+
#[test]
588+
fn fmt_binary_from_trait() {
589+
fn format_int<T: crate::Integer>(n: T) -> alloc::string::String {
590+
format!("{n:b}")
591+
}
592+
let n = U128::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd");
593+
assert_eq!(
594+
format_int(n),
595+
"10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
596+
);
597+
}
598+
526599
#[test]
527600
fn from_bytes() {
528601
let a = U128::from_be_hex("AAAAAAAABBBBBBBB0CCCCCCCDDDDDDDD");

src/uint/boxed.rs

+40-3
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,12 @@ impl fmt::Binary for BoxedUint {
375375
return fmt::Binary::fmt(&Limb::ZERO, f);
376376
}
377377

378+
if f.alternate() {
379+
write!(f, "0b")?;
380+
}
381+
378382
for limb in self.limbs.iter().rev() {
379-
fmt::Binary::fmt(limb, f)?;
383+
write!(f, "{:0width$b}", &limb.0, width = Limb::BITS as usize)?;
380384
}
381385
Ok(())
382386
}
@@ -388,8 +392,11 @@ impl fmt::LowerHex for BoxedUint {
388392
return fmt::LowerHex::fmt(&Limb::ZERO, f);
389393
}
390394

395+
if f.alternate() {
396+
write!(f, "0x")?;
397+
}
391398
for limb in self.limbs.iter().rev() {
392-
fmt::LowerHex::fmt(limb, f)?;
399+
write!(f, "{:0width$x}", &limb.0, width = Limb::BYTES * 2)?;
393400
}
394401
Ok(())
395402
}
@@ -401,8 +408,11 @@ impl fmt::UpperHex for BoxedUint {
401408
return fmt::LowerHex::fmt(&Limb::ZERO, f);
402409
}
403410

411+
if f.alternate() {
412+
write!(f, "0x")?;
413+
}
404414
for limb in self.limbs.iter().rev() {
405-
fmt::UpperHex::fmt(limb, f)?;
415+
write!(f, "{:0width$X}", &limb.0, width = Limb::BYTES * 2)?;
406416
}
407417
Ok(())
408418
}
@@ -421,4 +431,31 @@ mod tests {
421431
assert_eq!(uint.nlimbs(), 4);
422432
assert_eq!(uint.as_words(), words);
423433
}
434+
435+
#[test]
436+
fn fmt_lower_hex() {
437+
let n = BoxedUint::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD", 128).unwrap();
438+
assert_eq!(format!("{n:x}"), "aaaaaaaabbbbbbbbccccccccdddddddd");
439+
assert_eq!(format!("{n:#x}"), "0xaaaaaaaabbbbbbbbccccccccdddddddd");
440+
}
441+
442+
#[test]
443+
fn fmt_upper_hex() {
444+
let n = BoxedUint::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd", 128).unwrap();
445+
assert_eq!(format!("{n:X}"), "AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
446+
assert_eq!(format!("{n:#X}"), "0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD");
447+
}
448+
449+
#[test]
450+
fn fmt_binary() {
451+
let n = BoxedUint::from_be_hex("aaaaaaaabbbbbbbbccccccccdddddddd", 128).unwrap();
452+
assert_eq!(
453+
format!("{n:b}"),
454+
"10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
455+
);
456+
assert_eq!(
457+
format!("{n:#b}"),
458+
"0b10101010101010101010101010101010101110111011101110111011101110111100110011001100110011001100110011011101110111011101110111011101"
459+
);
460+
}
424461
}

0 commit comments

Comments
 (0)