diff --git a/CHANGELOG.md b/CHANGELOG.md index eaf97bc6412..80cc9e080ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ * Fixed many proc-macro generated `impl` blocks missing `#[automatically_derived]`, affecting test coverage. [#4078](https://github.com/rustwasm/wasm-bindgen/pull/4078) +* Fixed negative `BigInt` values being incorrectly formatted with two minus signs. + [#4082](https://github.com/rustwasm/wasm-bindgen/pull/4082) + -------------------------------------------------------------------------------- ## [0.2.93](https://github.com/rustwasm/wasm-bindgen/compare/0.2.92...0.2.93) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index a9f57d0c20e..8d64a937e41 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -1387,6 +1387,16 @@ impl BigInt { .pow(JsValue::as_ref(rhs)) .unchecked_into() } + + /// Returns a tuple of this [`BigInt`]'s absolute value along with a + /// [`bool`] indicating whether the [`BigInt`] was negative. + fn abs(&self) -> (Self, bool) { + if self >= &BigInt::from(0) { + (self.clone(), false) + } else { + (-self, true) + } + } } macro_rules! bigint_from { @@ -1493,41 +1503,42 @@ impl fmt::Debug for BigInt { impl fmt::Display for BigInt { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad_integral(self >= &BigInt::from(0), "", &self.to_string_unchecked(10)) + let (abs, is_neg) = self.abs(); + f.pad_integral(is_neg, "", &abs.to_string_unchecked(10)) } } impl fmt::Binary for BigInt { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad_integral(self >= &BigInt::from(0), "0b", &self.to_string_unchecked(2)) + let (abs, is_neg) = self.abs(); + f.pad_integral(is_neg, "0b", &abs.to_string_unchecked(2)) } } impl fmt::Octal for BigInt { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad_integral(self >= &BigInt::from(0), "0o", &self.to_string_unchecked(8)) + let (abs, is_neg) = self.abs(); + f.pad_integral(is_neg, "0o", &abs.to_string_unchecked(8)) } } impl fmt::LowerHex for BigInt { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad_integral( - self >= &BigInt::from(0), - "0x", - &self.to_string_unchecked(16), - ) + let (abs, is_neg) = self.abs(); + f.pad_integral(is_neg, "0x", &abs.to_string_unchecked(16)) } } impl fmt::UpperHex for BigInt { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s: String = self.to_string_unchecked(16); + let (abs, is_neg) = self.abs(); + let mut s: String = abs.to_string_unchecked(16); s.make_ascii_uppercase(); - f.pad_integral(self >= &BigInt::from(0), "0x", &s) + f.pad_integral(is_neg, "0x", &s) } }