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
use super::types::ListMarketsResponse;
use crate::errors::{ProtocolError, Result};
use crate::graphql::list_markets;
use crate::types::{Asset, Market};
use std::collections::HashMap;
use std::convert::TryFrom;
fn decimal_str_to_precision(decimal_str: &str) -> Result<u32> {
let parts: Vec<&str> = decimal_str.split(".").collect();
if parts.len() != 2 {
return Err(ProtocolError("Invalid format for decimal string"));
}
Ok(parts[1].len() as u32)
}
impl TryFrom<list_markets::ResponseData> for ListMarketsResponse {
type Error = ProtocolError;
fn try_from(response: list_markets::ResponseData) -> Result<Self> {
let mut markets = HashMap::new();
for market_data in response.list_markets {
let market_name = market_data.name;
if market_data.primary == false {
continue;
}
let asset_a_str = market_data.a_asset.symbol;
let asset_b_str = market_data.b_asset.symbol;
let asset_a = Asset::from_str(&asset_a_str);
let asset_b = Asset::from_str(&asset_b_str);
if let (Ok(asset_a), Ok(asset_b)) = (asset_a, asset_b) {
let precision_a =
decimal_str_to_precision(&market_data.min_trade_increment).expect("Impossible given 'decimal_str_to_precision' unless ME returns garbage for a precision");
let precision_b =
decimal_str_to_precision(&market_data.min_trade_increment_b).expect("Impossible given 'decimal_str_to_precision' unless ME returns garbage for b precision");
let prec_asset_a = asset_a.with_precision(precision_a);
let prec_asset_b = asset_b.with_precision(precision_b);
let min_trade_size_a = prec_asset_a.with_amount(&market_data.min_trade_size)?;
let min_trade_size_b = prec_asset_b.with_amount(&market_data.min_trade_size_b)?;
markets.insert(
market_name,
Market::new(
prec_asset_a,
prec_asset_b,
min_trade_size_a,
min_trade_size_b,
),
);
}
}
Ok(Self { markets })
}
}