Skip to content

Instantly share code, notes, and snippets.

@mymtw
Created July 10, 2022 12:01
Show Gist options
  • Save mymtw/3a3fa74ce7f5837e36e259d9a949bb0b to your computer and use it in GitHub Desktop.
Save mymtw/3a3fa74ce7f5837e36e259d9a949bb0b to your computer and use it in GitHub Desktop.
pub const WEI_IN_ETHER: U256 = U256([0x0de0b6b3a7640000, 0x0, 0x0, 0x0]);
#[derive(Debug)]
pub enum ConversionError {
UnrecognizedUnits(String),
TextTooLong,
}
/// Common Ethereum unit types.
pub enum Units {
/// Ether corresponds to 1e18 Wei
Ether,
/// Gwei corresponds to 1e9 Wei
Gwei,
/// Wei corresponds to 1 Wei
Wei,
/// Use this for other less frequent unit sizes
Other(u32),
}
impl Units {
pub fn as_num(&self) -> u32 {
match self {
Units::Ether => 18,
Units::Gwei => 9,
Units::Wei => 0,
Units::Other(inner) => *inner,
}
}
}
use std::convert::TryFrom;
impl TryFrom<u32> for Units {
type Error = ConversionError;
fn try_from(src: u32) -> Result<Self, Self::Error> {
Ok(Units::Other(src))
}
}
impl TryFrom<i32> for Units {
type Error = ConversionError;
fn try_from(src: i32) -> Result<Self, Self::Error> {
Ok(Units::Other(src as u32))
}
}
impl TryFrom<usize> for Units {
type Error = ConversionError;
fn try_from(src: usize) -> Result<Self, Self::Error> {
Ok(Units::Other(src as u32))
}
}
impl std::convert::TryFrom<&str> for Units {
type Error = ConversionError;
fn try_from(src: &str) -> Result<Self, Self::Error> {
Ok(match src.to_lowercase().as_str() {
"ether" => Units::Ether,
"gwei" => Units::Gwei,
"wei" => Units::Wei,
_ => return Err(ConversionError::UnrecognizedUnits(src.to_string())),
})
}
}
pub fn format_units<T, K>(amount: T, units: K) -> Result<String, ConversionError>
where
T: Into<U256>,
K: TryInto<Units, Error = ConversionError>,
{
let units = units.try_into()?;
let amount = amount.into();
let amount_decimals = amount % U256::from(10_u128.pow(units.as_num()));
let amount_integer = amount / U256::from(10_u128.pow(units.as_num()));
Ok(format!(
"{}.{:0width$}",
amount_integer,
amount_decimals.as_u128(),
width = units.as_num() as usize
))
}
let amount = U256::from_dec_str("1000").unwrap();
let amount = format_units(amount, "ether").unwrap();
info!("x: {:?}", Decimal::from_str(&amount).unwrap());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment