From b09e3f784cad54160570f5c4df09bf3682c47786 Mon Sep 17 00:00:00 2001 From: Cristian Filipescu Date: Mon, 8 Nov 2021 23:27:14 -0500 Subject: [PATCH] fix: changed format_units to return a String and preserve the decimal places --- CHANGELOG.md | 1 + ethers-core/src/utils/mod.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d717b4b550..86b3fadc14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Remove unnecessary `Serialize` constraint to `R` (the Response type) in the `request` method of `JsonRpcClient`. - Fix `http Provider` data race when generating new request `id`s. - Add support for `net_version` RPC method. [595](https://github.com/gakonst/ethers-rs/pull/595) +- Fix `format_units` to return a `String` of representing a decimal point float such that the decimal places don't get truncated. [597](https://github.com/gakonst/ethers-rs/pull/597) ### 0.5.3 diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs index 0099e2e481..7b16f1a5ea 100644 --- a/ethers-core/src/utils/mod.rs +++ b/ethers-core/src/utils/mod.rs @@ -58,10 +58,25 @@ pub fn format_ether>(amount: T) -> U256 { } /// Divides the provided amount with 10^{units} provided. -pub fn format_units, K: Into>(amount: T, units: K) -> U256 { +/// +/// ``` +/// use ethers_core::{types::U256, utils::format_units}; +/// +/// let eth = format_units(1395633240123456000_u128, "ether"); +/// assert_eq!(eth.parse::().unwrap(), 1.395633240123456); +/// +/// let eth = format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether"); +/// assert_eq!(eth.parse::().unwrap(), 1.395633240123456); +/// +/// let eth = format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether"); +/// assert_eq!(eth, "1.395633240123456789"); +/// ``` +pub fn format_units, K: Into>(amount: T, units: K) -> String { let units = units.into(); let amount = amount.into(); - amount / 10u64.pow(units.as_num()) + let amount_decimals = amount % U256::from(10_u128.pow(units.as_num())); + let amount_integer = amount / U256::from(10_u128.pow(units.as_num())); + amount_integer.to_string() + "." + &amount_decimals.to_string() } /// Converts the input to a U256 and converts from Ether to Wei. @@ -367,10 +382,19 @@ mod tests { #[test] fn test_format_units() { let gwei_in_ether = format_units(WEI_IN_ETHER, 9); - assert_eq!(gwei_in_ether.as_u64(), 1e9 as u64); + assert_eq!(gwei_in_ether.parse::().unwrap() as u64, 1e9 as u64); let eth = format_units(WEI_IN_ETHER, "ether"); - assert_eq!(eth.as_u64(), 1); + assert_eq!(eth.parse::().unwrap() as u64, 1); + + let eth = format_units(1395633240123456000_u128, "ether"); + assert_eq!(eth.parse::().unwrap(), 1.395633240123456); + + let eth = format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether"); + assert_eq!(eth.parse::().unwrap(), 1.395633240123456); + + let eth = format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether"); + assert_eq!(eth, "1.395633240123456789"); } #[test]