Created
July 10, 2022 12:01
-
-
Save mymtw/3a3fa74ce7f5837e36e259d9a949bb0b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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