Skip to content

Commit

Permalink
refactor: Refactored the FunglibleToken implementation and the usage
Browse files Browse the repository at this point in the history
  • Loading branch information
frol committed Jan 29, 2024
1 parent 7b8f5c3 commit 45c7650
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 68 deletions.
42 changes: 10 additions & 32 deletions src/commands/tokens/send_ft/amount_ft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ impl AmountFtContext {
&network_config,
near_primitives::types::Finality::Final.into(),
)?;
let amount_ft = scope.amount_ft.normalize(&ft_metadata)?;

Ok(Self {
global_context: previous_context.global_context,
signer_account_id: previous_context.signer_account_id,
ft_contract_account_id: previous_context.ft_contract_account_id,
receiver_account_id: previous_context.receiver_account_id,
amount_ft,
amount_ft: scope.amount_ft.normalize(&ft_metadata)?,
})
}
}
Expand All @@ -82,41 +81,20 @@ impl AmountFt {
)?;
eprintln!();

let symbol = ft_metadata.symbol.clone();
Ok(Some(
CustomType::<crate::types::ft_properties::FungibleToken>::new(&format!(
"Enter an amount FT to transfer (example: 10{symbol} or 0.5{symbol}):"
"Enter an FT amount to transfer (example: 10 {symbol} or 0.5 {symbol}):",
symbol = ft_metadata.symbol
))
.with_validator(move |ft: &crate::types::ft_properties::FungibleToken| {
if let Err(err) = ft.normalize(&ft_metadata.clone()) {
return Ok(inquire::validator::Validation::Invalid(
match ft.normalize(&ft_metadata) {
Err(err) => Ok(inquire::validator::Validation::Invalid(
inquire::validator::ErrorMessage::Custom(err.to_string()),
));
}
Ok(inquire::validator::Validation::Valid)
})
.with_formatter(&|ft| {
let one_ft: u128 = 10u128
.checked_pow(ft.decimals().into())
.expect("FT Balance: overflow happens");
if ft.amount() == 0 {
format!("0 {}", symbol)
} else if ft.amount() % one_ft == 0 {
format!("{} {}", ft.amount() / one_ft, symbol)
} else {
format!(
"{}.{} {}",
ft.amount() / one_ft,
format!(
"{:0>decimals$}",
(ft.amount() % one_ft),
decimals = ft.decimals().into()
)
.trim_end_matches('0'),
symbol
)
)),
Ok(_) => Ok(inquire::validator::Validation::Valid),
}
})
.with_formatter(&|ft| ft.to_string())
.prompt()?,
))
}
Expand Down Expand Up @@ -175,7 +153,7 @@ impl PrepaidGas {
if input_gas <= near_gas::NearGas::from_tgas(300) {
break input_gas;
} else {
eprintln!("You need to enter a value of no more than 300 TERAGAS")
eprintln!("You need to enter a value of no more than 300 TeraGas")
}
}
Err(err) => return Err(color_eyre::Report::msg(err)),
Expand Down Expand Up @@ -317,7 +295,7 @@ impl Deposit {
eprintln!();
match crate::types::near_token::NearToken::from_str(
&Text::new(
"Enter deposit for a function call (example: 10NEAR or 0.5near or 10000yoctonear):",
"Enter deposit for a function call (example: 10 NEAR or 0.5 near or 10000 yoctonear):",
)
.with_initial_value("1 yoctoNEAR")
.prompt()?,
Expand Down
66 changes: 30 additions & 36 deletions src/types/ft_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,30 @@ impl FungibleToken {
}

pub fn normalize(&self, ft_metadata: &FtMetadata) -> color_eyre::eyre::Result<Self> {
if ft_metadata.decimals < u64::from(self.decimals) {
color_eyre::eyre::Result::Err(color_eyre::eyre::eyre!(
if ft_metadata.symbol.to_uppercase() != self.symbol.to_uppercase() {
color_eyre::eyre::bail!("Invalid currency symbol")
} else if let Some(decimals_diff) = ft_metadata.decimals.checked_sub(self.decimals) {
let amount = if decimals_diff == 0 {
self.amount
} else {
self.amount
.checked_mul(
10u128
.checked_pow(decimals_diff.into())
.wrap_err("Overflow in decimal normalization")?,
)
.wrap_err("Overflow in decimal normalization")?
};
Ok(Self {
symbol: ft_metadata.symbol.clone(),
decimals: ft_metadata.decimals,
amount,
})
} else {
color_eyre::eyre::bail!(
"Invalid decimal places. Your FT amount exceeds {} decimal places.",
ft_metadata.decimals
))
} else if ft_metadata.symbol.to_uppercase() != self.symbol.to_uppercase() {
color_eyre::eyre::Result::Err(color_eyre::eyre::eyre!("Invalid currency symbol"))
} else if ft_metadata.symbol == self.symbol
&& ft_metadata.decimals == u64::from(self.decimals)
{
Ok(self.clone())
} else {
let mut fungible_token = self.clone();
let actual_decimals = u32::try_from(ft_metadata.decimals)
.wrap_err("Error converting u64 to u32")?
.checked_sub(fungible_token.decimals().into())
.wrap_err("FT Balance: underflow or overflow happens")?;
fungible_token.amount = fungible_token
.amount
.checked_mul(
10u128
.checked_pow(actual_decimals)
.wrap_err("FT Balance: overflow happens")?,
)
.wrap_err("FungibleToken: overflow happens")?;
fungible_token.decimals = ft_metadata
.decimals
.try_into()
.wrap_err("Error converting u64 to u8")?;
fungible_token.symbol = ft_metadata.symbol.clone();
Ok(fungible_token)
)
}
}

Expand All @@ -62,16 +55,16 @@ impl FungibleToken {
self.decimals
}

pub fn symbol(&self) -> String {
self.symbol.to_owned()
pub fn symbol(&self) -> &str {
&self.symbol
}
}

impl std::fmt::Display for FungibleToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let one_ft: u128 = 10u128
.checked_pow(self.decimals.into())
.wrap_err("FT Balance: overflow happens")
.wrap_err("Overflow in FungibleToken normalization")
.unwrap();
if self.amount == 0 {
write!(f, "0 {}", self.symbol)
Expand All @@ -96,6 +89,7 @@ impl std::fmt::Display for FungibleToken {

impl std::str::FromStr for FungibleToken {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let num = s.trim().trim_end_matches(char::is_alphabetic).trim();
let currency = s.trim().trim_start_matches(num).trim().to_string();
Expand All @@ -109,7 +103,7 @@ impl std::str::FromStr for FungibleToken {
.trim_end_matches('0')
.len()
.try_into()
.map_err(|_| "Error converting usize to u8")?;
.map_err(|_| "Error converting len_fract to u8")?;
let num_fract_part = res_split[1]
.trim_end_matches('0')
.parse::<u128>()
Expand All @@ -123,7 +117,7 @@ impl std::str::FromStr for FungibleToken {
.ok_or("FungibleToken: overflow happens")?
.checked_add(num_fract_part)
.ok_or("FungibleToken: overflow happens")?;
Ok(FungibleToken {
Ok(Self {
amount,
decimals: len_fract,
symbol: currency,
Expand All @@ -136,7 +130,7 @@ impl std::str::FromStr for FungibleToken {
let amount = res_split[0]
.parse::<u128>()
.map_err(|err| format!("FungibleToken: {}", err))?;
Ok(FungibleToken {
Ok(Self {
amount,
decimals: 0,
symbol: currency,
Expand All @@ -154,7 +148,7 @@ impl interactive_clap::ToCli for FungibleToken {
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, serde::Deserialize)]
pub struct FtMetadata {
pub symbol: String,
pub decimals: u64,
pub decimals: u8,
}

pub fn params_ft_metadata(
Expand Down

0 comments on commit 45c7650

Please sign in to comment.