1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#![allow(dead_code)]
use std::convert::TryFrom;
use hashbrown::HashMap;
use cxmr_api_clients_errors::Error;
use cxmr_balances::{points, Balance};
use cxmr_exchanges::AccountInfo;
#[derive(Deserialize)]
pub struct BncAccount {
#[serde(rename = "makerCommission")]
maker_commission: u64,
#[serde(rename = "takerCommission")]
taker_commission: u64,
#[serde(rename = "buyerCommission")]
buyer_commission: u64,
#[serde(rename = "sellerCommission")]
seller_commission: u64,
#[serde(rename = "canTrade")]
can_trade: bool,
#[serde(rename = "canWithdraw")]
can_withdraw: bool,
#[serde(rename = "canDeposit")]
can_deposit: bool,
#[serde(rename = "updateTime")]
update_time: u64,
balances: Vec<BncBalance>,
}
impl ::std::convert::TryFrom<BncAccount> for AccountInfo {
type Error = Error;
#[inline]
fn try_from(acc: BncAccount) -> Result<AccountInfo, Error> {
let mut balances = HashMap::new();
acc.balances.into_iter().for_each(|b| {
let bnc = Balance::try_from(&b).unwrap();
balances.insert(b.asset.as_str().into(), bnc);
});
Ok(AccountInfo {
account: "".to_owned(),
maker_fee_rate: acc.maker_commission,
taker_fee_rate: acc.taker_commission,
can_trade: acc.can_trade,
balances: balances,
updated_at: acc.update_time,
})
}
}
#[derive(Deserialize)]
pub struct BncBalance {
asset: String,
free: String,
locked: String,
}
impl TryFrom<&BncBalance> for Balance {
type Error = Error;
#[inline]
fn try_from(b: &BncBalance) -> Result<Balance, Error> {
let unused = points(b.free.parse()?);
let in_use = points(b.locked.parse()?);
Ok(Balance {
total: unused + in_use,
unused: unused,
in_use: in_use,
total_btc: None,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
use cxmr_currency::Currency;
#[bench]
fn find_balance_map(b: &mut Bencher) {
let account: BncAccount =
::serde_json::from_str(include_str!("../../../testdata/account.v3.json")).unwrap();
let account = AccountInfo::try_from(account).unwrap();
b.iter(|| {
let _balance = account.balances.get(&Currency::Usdc).unwrap();
let _balance = account.balances.get(&Currency::Btc).unwrap();
});
}
#[test]
fn get_balance() {
let account: BncAccount =
::serde_json::from_str(include_str!("../../../testdata/account.v3.json")).unwrap();
let account = AccountInfo::try_from(account).unwrap();
let balance = account.balances.get(&Currency::Btc).unwrap();
assert_eq!(1, balance.in_use);
assert_eq!(2452, balance.unused);
let balance = account.balances.get(&Currency::Eth).unwrap();
assert_eq!(0, balance.in_use);
assert_eq!(805792263, balance.unused);
let balance = account.balances.get(&Currency::Bnb).unwrap();
assert_eq!(0, balance.in_use);
assert_eq!(362829719, balance.unused);
let balance = account.balances.get(&Currency::Bchabc).unwrap();
assert_eq!(0, balance.in_use);
assert_eq!(192000000, balance.unused);
}
}