diff --git a/src/chain/chain_type.rs b/src/chain/chain_type.rs index 608e19f..e1ae45f 100644 --- a/src/chain/chain_type.rs +++ b/src/chain/chain_type.rs @@ -1,4 +1,4 @@ -use std::str::FromStr; +use std::{fmt::Display, str::FromStr}; use serde::{Deserialize, Serialize}; @@ -22,14 +22,17 @@ impl ChainType { } } -impl ToString for ChainType { - fn to_string(&self) -> String { - match self { - Self::Evm => "evm", - Self::Solana => "sol", - Self::Ton => "ton", - } - .to_string() +impl Display for ChainType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Evm => "evm", + Self::Solana => "sol", + Self::Ton => "ton", + } + ) } } diff --git a/src/chain/evm_chain.rs b/src/chain/evm_chain.rs index 917783a..3fc78b0 100644 --- a/src/chain/evm_chain.rs +++ b/src/chain/evm_chain.rs @@ -56,7 +56,7 @@ impl EvmChain { .json::() .await .ok() - .and_then(|x| Some(x.result)), + .map(|x| x.result), seconds, ) } @@ -111,9 +111,7 @@ impl ChainOps for EvmChain { "latest" ]); let decimals_hex = self.rpc_call("eth_call", params, rpc_index).await.0?; - BigUint::parse_bytes(&decimals_hex.as_bytes()[2..], 16)? - .to_usize() - .into() + BigUint::parse_bytes(&decimals_hex.as_bytes()[2..], 16)?.to_usize() } async fn scan_for_tokens( &self, @@ -130,7 +128,7 @@ impl ChainOps for EvmChain { if address.len() != 40 { return None; } - if !address.chars().all(|c| c.is_digit(16)) { + if !address.chars().all(|c| c.is_ascii_hexdigit()) { return None; } let mut hasher = Keccak256::new(); diff --git a/src/chain/mod.rs b/src/chain/mod.rs index 745e498..e02fb29 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -67,7 +67,7 @@ pub trait ChainOps { async fn get_token_decimals(&self, token_address: &str, rpc_index: usize) -> Option; async fn get_token_symbol(&self, token_address: &str, _rpc_index: usize) -> Option { let pairs = dexscreener::pairs::get_pairs(vec![token_address]).await?; - (pairs.len() != 0).then(|| pairs[0].base_token.symbol.clone()) + (!pairs.is_empty()).then(|| pairs[0].base_token.symbol.clone()) } async fn get_holdings_balance( &self, diff --git a/src/chain/sol_chain.rs b/src/chain/sol_chain.rs index b1eb97a..d13ecc0 100644 --- a/src/chain/sol_chain.rs +++ b/src/chain/sol_chain.rs @@ -123,7 +123,7 @@ impl ChainOps for SolChain { let (balances, wait_time) = self .rpc_call::("getTokenAccountsByOwner", params, rpc_index) .await; - if balances.is_some() && balances.clone().unwrap().token_amounts.len() == 0 { + if balances.is_some() && balances.clone().unwrap().token_amounts.is_empty() { return (Some(BigUint::ZERO), wait_time); } ( diff --git a/src/chain/token.rs b/src/chain/token.rs index f0f5c72..63ba742 100644 --- a/src/chain/token.rs +++ b/src/chain/token.rs @@ -23,7 +23,7 @@ impl Token { let symbol = chain.get_token_symbol(address, 0).await?; Some(Self { symbol, - address: chain.parse_token_address(&address)?, + address: chain.parse_token_address(address)?, decimals, }) } @@ -33,7 +33,7 @@ impl Token { if mag > 0 { value.insert(mag as usize, '.'); } else { - value = format!("0.{}{value}", "0".repeat(mag.abs() as usize)); + value = format!("0.{}{value}", "0".repeat(mag.unsigned_abs())); } value.parse().unwrap() } diff --git a/src/chain/ton_chain.rs b/src/chain/ton_chain.rs index fb0b471..0cc2cd5 100644 --- a/src/chain/ton_chain.rs +++ b/src/chain/ton_chain.rs @@ -73,12 +73,7 @@ impl TonChain { route: String, query_pairs: Vec<(&str, &str)>, ) -> (Option, Option) { - let mut url = Url::parse(&format!( - "{}/{}", - self.properties.rpc_urls[0].to_string(), - route - )) - .unwrap(); + let mut url = Url::parse(&format!("{}/{}", self.properties.rpc_urls[0], route)).unwrap(); url.query_pairs_mut().extend_pairs(query_pairs); let response = match self .http_client @@ -105,10 +100,7 @@ impl ChainOps for TonChain { let (balance, wait_time) = self .api_call::(format!("accounts/{address}"), vec![]) .await; - ( - balance.and_then(|b| Some(BigUint::from(b.balance))), - wait_time, - ) + (balance.map(|b| BigUint::from(b.balance)), wait_time) } async fn get_token_balance( &self, @@ -132,9 +124,9 @@ impl ChainOps for TonChain { address: &str, _rpc_index: usize, ) -> SupportOption> { - let address = self.parse_wallet_address(&address).to_supported()?; + let address = self.parse_wallet_address(address).to_supported()?; self.api_call::( - format!("accounts/{}/jettons", address), + format!("accounts/{address}/jettons"), vec![], ) .await @@ -161,12 +153,11 @@ impl ChainOps for TonChain { .decimals, ) .ok() - .into() } async fn scan_for_tokens(&self, address: &str, _rpc_index: usize) -> SupportOption> { - let address = self.parse_wallet_address(&address).to_supported()?; + let address = self.parse_wallet_address(address).to_supported()?; self.api_call::( - format!("accounts/{}/jettons", address), + format!("accounts/{address}/jettons"), vec![], ) .await diff --git a/src/dexscreener/pairs.rs b/src/dexscreener/pairs.rs index e5d9629..c705f2c 100644 --- a/src/dexscreener/pairs.rs +++ b/src/dexscreener/pairs.rs @@ -60,7 +60,7 @@ where let pairs = stream::iter(tokens.clone()) .map(async |t| { let url = Url::from_str( - format!("https://api.dexscreener.com/latest/dex/tokens/{}", t).as_str(), + format!("https://api.dexscreener.com/latest/dex/tokens/{t}").as_str(), ) .unwrap(); let task = async |_rpc_index| (get_pairs_request(url.clone()).await, None); diff --git a/src/main.rs b/src/main.rs index 927f435..56c226a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,6 @@ async fn main() { } } if let Err(err) = Repl::default().run().await { - eprintln!("Error: {}", err); + eprintln!("Error: {err}"); } } diff --git a/src/repl/data_file.rs b/src/repl/data_file.rs index b4edffe..8fabc28 100644 --- a/src/repl/data_file.rs +++ b/src/repl/data_file.rs @@ -17,7 +17,7 @@ pub fn data_file_exists() -> Result { pub fn read_data_file() -> Result, String> { match std::fs::read(get_data_file_path()?) { Ok(x) => Ok(x), - _ => return Err("Could not read data file".to_string()), + _ => Err("Could not read data file".to_string()), } } diff --git a/src/repl/mod.rs b/src/repl/mod.rs index b9fb334..e07dfbd 100644 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -126,8 +126,7 @@ impl Repl { { Some(x) => Ok(x), None => Err(format!( - "There is no available chain with name {:?}", - chain_name + "There is no available chain with name {chain_name:?}", )), } } @@ -138,10 +137,10 @@ impl Repl { .iter() .find_map(|(chain_type, address, alias)| { (account == address || alias.clone().is_some_and(|alias| alias == account)) - .then(|| (chain_type, address)) + .then_some((chain_type, address)) }) { Some(x) => Ok(x), - _ => Err(format!("Found no account corresponding to {:?}", account)), + _ => Err(format!("Found no account corresponding to {account:?}")), } } fn format_address(a: &str) -> String { @@ -149,7 +148,7 @@ impl Repl { let last = &a[a.len() - 5..].to_string(); format!("{first}..{last}") } - fn format_account(address: &String, alias: &Option) -> String { + fn format_account(address: &str, alias: &Option) -> String { if alias.is_some() { return alias.clone().unwrap(); } @@ -293,7 +292,7 @@ can use the same command to set an authentication token for the API. let chain_name = self.find_chain(arg)?.properties.name.clone(); self.config.rpcs.remove_entry(arg); self.store_config_to_data_file()?; - println!("{} chain set back to default state", chain_name); + println!("{chain_name} chain set back to default state"); Ok(()) } "toggle" => { @@ -340,7 +339,7 @@ can use the same command to set an authentication token for the API. let arg = command_parts[2]; let chain = self.find_chain(chain_id)?; if chain.chain_type != ChainType::Ton && Url::from_str(arg).is_err() { - return Err(format!("{:?} is not a valid url", arg)); + return Err(format!("{arg:?} is not a valid url")); } self.config .rpcs @@ -374,7 +373,7 @@ alias, if set. ]) }) .collect::>(); - if rows.len() == 0 { + if rows.is_empty() { continue; } rows.insert( @@ -450,7 +449,7 @@ alias, if set. Vec::from([t.symbol.clone(), t.address.clone(), t.decimals.to_string()]) }) .collect::>(); - if tokens.len() == 0 { + if tokens.is_empty() { continue; } tokens.insert( @@ -483,14 +482,13 @@ alias, if set. )) } }; - let token = match Token::new(&token_address, &chain).await { + let token = match Token::new(&token_address, chain).await { Some(x) => x, None => return Err("Could not fetch token info".to_string()), }; if self .tokens_of_chain(chain) - .find(|(_, t)| t.address == token.address) - .is_some() + .any(|(_, t)| t.address == token.address) { return Err("Token already added".to_string()); } @@ -516,8 +514,7 @@ alias, if set. Some(x) => self.config.tokens.remove(x), None => { return Err(format!( - "Could not find token with address {:?}", - token_address + "Could not find token with address {token_address:?}", )) } }; @@ -542,10 +539,10 @@ alias, if set. let new_tokens = tokens_found .into_iter() .filter_map(|t| { - self.tokens_of_chain(chain) - .find(|(_, ct)| ct.address == t.address) - .is_none() - .then(|| (chain_id.to_string(), t)) + (!self + .tokens_of_chain(chain) + .any(|(_, ct)| ct.address == t.address)) + .then(|| (chain_id.to_string(), t)) }) .collect::>(); let new_tokens_len = new_tokens.len(); @@ -554,7 +551,7 @@ alias, if set. if new_tokens_len == 0 { println!("Found no new tokens"); } else { - println!("{} new tokens added", new_tokens_len); + println!("{new_tokens_len} new tokens added"); } Ok(()) } @@ -577,7 +574,7 @@ alias, if set. .accounts .iter() .flat_map(|(chain_type, address, alias)| { - self.enabled_chains_of_type(&chain_type) + self.enabled_chains_of_type(chain_type) .map(move |chain| (chain, address, alias)) }) .partition(|(chain, _, _)| chain.chain_type == ChainType::Ton); @@ -585,7 +582,7 @@ alias, if set. let accounts_not_supported = accounts_not_supported .iter() .flat_map(|(chain, address, alias)| { - self.tokens_of_chain(&chain) + self.tokens_of_chain(chain) .map(move |(_, token)| (chain, token.clone(), address, alias)) }) .collect::>(); @@ -688,11 +685,8 @@ alias, if set. account_holdings .iter() .filter_map(move |(token_address, balance)| { - let Some((_, token)) = - tokens_of_chain.find(|(_, t)| t.address == *token_address) - else { - return None; - }; + let (_, token) = + tokens_of_chain.find(|(_, t)| t.address == *token_address)?; (*balance != BigUint::ZERO).then(|| ReplBalanceEntry { account: account_label.clone(), chain: chain.properties.name.clone(), @@ -721,7 +715,7 @@ alias, if set. .await { Some(x) => x, - None => return Err(format!("Could not fetch tokens price")), + None => return Err("Could not fetch tokens price".to_string()), } .iter() .filter_map(|p| { @@ -732,8 +726,7 @@ alias, if set. self.spinner.stop(); - for i in 0..balances.len() { - let balance = &mut balances[i]; + for balance in &mut balances { if let Some((_, price)) = pairs.iter().find(|pair| pair.0 == balance.token.address) { @@ -795,7 +788,10 @@ alias, if set. "chain" => self.handle_chain(command_parts), "account" => self.handle_account(command_parts), "config" => self.handle_config(command_parts), - "help" | "?" => Ok(Self::display_help()), + "help" | "?" => { + Self::display_help(); + Ok(()) + } "exit" | "quit" => std::process::exit(0), x => Err(format!("Unknown command: {x:?}")), } { diff --git a/src/utils/spinner.rs b/src/utils/spinner.rs index bb427c8..91da17d 100644 --- a/src/utils/spinner.rs +++ b/src/utils/spinner.rs @@ -53,9 +53,7 @@ impl Spinner { let output = format!( "\r{}{}{}{}", FRAMES[i].to_colored(), - extra_msg - .and_then(|s| Some(format!(" {s}"))) - .unwrap_or_default(), + extra_msg.map(|s| format!(" {s}")).unwrap_or_default(), if show_progress { format!( " {}/{}", diff --git a/src/utils/table.rs b/src/utils/table.rs index 2ab1067..c8970e1 100644 --- a/src/utils/table.rs +++ b/src/utils/table.rs @@ -32,7 +32,7 @@ impl Default for Table { impl Display for Table { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self.rows.len() == 0 { + if self.rows.is_empty() { return write!(f, ""); } if self.title != String::default() { @@ -43,8 +43,8 @@ impl Display for Table { let col_count = self.rows[0].len(); let mut col_widths: Vec = vec![0; col_count]; for i in 0..row_count { - for j in 0..col_count { - col_widths[j] = (self.rows[i][j].len() + self.spacing).max(col_widths[j]); + for (j, col_width) in col_widths.iter_mut().enumerate().take(col_count) { + *col_width = (self.rows[i][j].len() + self.spacing).max(*col_width); } } for i in 0..row_count { diff --git a/src/utils/text.rs b/src/utils/text.rs index 335eae0..65a99e0 100644 --- a/src/utils/text.rs +++ b/src/utils/text.rs @@ -5,7 +5,7 @@ pub trait StylizedText { impl StylizedText for &str { fn to_colored(&self) -> String { - format!("\x1b[32m{}\x1b[0m", self) + format!("\x1b[32m{self}\x1b[0m") } fn to_title(&self) -> String { format!("{}\n{}", self, "=".repeat(self.len()))