use core::fmt; use std::borrow::Cow; use std::fmt::{Display, Formatter}; #[derive(Clone, PartialEq, Hash)] pub struct Symbol { name: Cow<'static, str> } impl From for Symbol where S: Into { fn from(item: S) -> Self { Symbol::new(item.into()) } } impl Symbol { pub const XMR: Symbol = Symbol::new_static("XMR"); pub const BTC: Symbol = Symbol::new_static("BTC"); pub const ETH: Symbol = Symbol::new_static("ETH"); pub const LTC: Symbol = Symbol::new_static("LTC"); pub const USD: Symbol = Symbol::new_static("USD"); pub const GBP: Symbol = Symbol::new_static("GBP"); pub const EUR: Symbol = Symbol::new_static("EUR"); pub fn new(name: String) -> Self { Symbol { name: Cow::from(name) } } pub const fn new_static(name: &'static str) -> Self { Symbol { name: Cow::Borrowed(name) } } pub fn name(&self) -> &str { &self.name } } impl Display for Symbol { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name) } } #[derive(Clone)] pub struct SymbolPair { quote: Symbol, base: Symbol, } impl SymbolPair { pub fn new(quote: Symbol, base: Symbol) -> Self { SymbolPair { quote, base } } pub fn trading_repr(&self) -> String { format!("t{}{}", self.quote, self.base) } pub fn funding_repr(&self) -> String { format!("f{}{}", self.quote, self.base) } pub fn quote(&self) -> &Symbol { &self.quote } pub fn base(&self) -> &Symbol { &self.base } } impl Into for SymbolPair { fn into(self) -> String { format!("{}{}", self.base, self.quote) } } impl Display for SymbolPair { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}{}", self.base, self.quote) } } #[derive(Clone)] enum WalletKind { Margin, Exchange, Funding, } #[derive(Clone)] struct Balance { pair: SymbolPair, base_price: f64, base_amount: f64, quote_equivalent: f64, wallet: WalletKind, } impl Balance { pub fn new(pair: SymbolPair, base_price: f64, base_amount: f64, wallet: WalletKind) -> Self { Balance { pair, base_price, base_amount, quote_equivalent: base_amount * base_price, wallet } } pub fn pair(&self) -> &SymbolPair { &self.pair } pub fn base_price(&self) -> f64 { self.base_price } pub fn base_amount(&self) -> f64 { self.base_amount } pub fn quote_equivalent(&self) -> f64 { self.quote_equivalent } pub fn wallet(&self) -> &WalletKind { &self.wallet } } struct BalanceGroup { quote_equivalent: f64, balances: Vec, } impl BalanceGroup { pub fn new() -> Self { BalanceGroup { balances: Vec::new(), quote_equivalent: 0f64 } } pub fn add_balance(&mut self, balance: &Balance) { self.balances.push(balance.clone()); self.quote_equivalent += balance.quote_equivalent() } pub fn currency_names(&self) -> Vec { self.balances.iter() .map(|x| x.pair().base().name().into()) .collect() } pub fn balances(&self) -> &Vec { &self.balances } }