fix: use decimal crate for parsing units (#1330)
This commit is contained in:
parent
e0db2f0606
commit
6a45a93685
|
@ -40,6 +40,7 @@ cargo_metadata = { version = "0.14.2", optional = true }
|
||||||
convert_case = { version = "0.5.0", optional = true }
|
convert_case = { version = "0.5.0", optional = true }
|
||||||
syn = { version = "1.0.95", optional = true }
|
syn = { version = "1.0.95", optional = true }
|
||||||
proc-macro2 = { version = "1.0.39", optional = true }
|
proc-macro2 = { version = "1.0.39", optional = true }
|
||||||
|
rust_decimal = "1.23.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = { version = "1.0.64", default-features = false }
|
serde_json = { version = "1.0.64", default-features = false }
|
||||||
|
|
|
@ -50,6 +50,8 @@ pub enum ConversionError {
|
||||||
InvalidFloat(#[from] std::num::ParseFloatError),
|
InvalidFloat(#[from] std::num::ParseFloatError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
FromDecStrError(#[from] FromDecStrErr),
|
FromDecStrError(#[from] FromDecStrErr),
|
||||||
|
#[error(transparent)]
|
||||||
|
DecimalError(#[from] rust_decimal::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
|
/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
|
||||||
|
@ -147,9 +149,12 @@ where
|
||||||
S: ToString,
|
S: ToString,
|
||||||
K: TryInto<Units, Error = ConversionError> + Copy,
|
K: TryInto<Units, Error = ConversionError> + Copy,
|
||||||
{
|
{
|
||||||
let float_n: f64 =
|
use rust_decimal::Decimal;
|
||||||
amount.to_string().parse::<f64>()? * 10u64.pow(units.try_into()?.as_num()) as f64;
|
let num: Decimal = amount.to_string().parse()?;
|
||||||
let u256_n: U256 = U256::from_dec_str(&float_n.round().to_string())?;
|
let multiplier: Decimal = 10u64.pow(units.try_into()?.as_num()).into();
|
||||||
|
let val =
|
||||||
|
num.checked_mul(multiplier).ok_or(rust_decimal::Error::ExceedsMaximumPossibleValue)?;
|
||||||
|
let u256_n: U256 = U256::from_dec_str(&val.round().to_string())?;
|
||||||
Ok(u256_n)
|
Ok(u256_n)
|
||||||
}
|
}
|
||||||
/// The address for an Ethereum contract is deterministically computed from the
|
/// The address for an Ethereum contract is deterministically computed from the
|
||||||
|
@ -446,6 +451,9 @@ mod tests {
|
||||||
|
|
||||||
let eth = parse_units(1, "ether").unwrap();
|
let eth = parse_units(1, "ether").unwrap();
|
||||||
assert_eq!(eth, WEI_IN_ETHER);
|
assert_eq!(eth, WEI_IN_ETHER);
|
||||||
|
|
||||||
|
let val = parse_units("2.3", "ether").unwrap();
|
||||||
|
assert_eq!(val, U256::from_dec_str("2300000000000000000").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue