use crate::client::{ApiError, Transport, info, info_request};
use crate::utils::{Address, Dec};
use serde::Deserialize;
#[must_use]
pub fn perp_dexs_request() -> String {
info_request("perpDexs", &[])
}
pub async fn perp_dexs(transport: &impl Transport) -> Result<PerpDexs, ApiError> {
info(transport, perp_dexs_request()).await
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(transparent)]
pub struct PerpDexs(pub Vec<Option<PerpDex>>);
impl PerpDexs {
pub fn dexes(&self) -> impl Iterator<Item = (u32, &PerpDex)> {
self.0.iter().enumerate().filter_map(|(at, dex)| Some((u32::try_from(at).ok()?, dex.as_ref()?)))
}
#[must_use]
pub fn index_of(&self, name: &str) -> Option<u32> {
self.dexes().find(|(_, dex)| dex.name == name).map(|(at, _)| at)
}
#[must_use]
pub fn get(&self, name: &str) -> Option<&PerpDex> {
self.dexes().find(|(_, dex)| dex.name == name).map(|(_, dex)| dex)
}
#[must_use]
pub fn name_of(&self, place: u32) -> Option<&str> {
self.0.get(usize::try_from(place).ok()?)?.as_ref().map(|dex| dex.name.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PerpDex {
pub name: String,
pub full_name: String,
#[serde(default)]
pub deployer: Option<Address>,
#[serde(default)]
pub oracle_updater: Option<Address>,
#[serde(default)]
pub fee_recipient: Option<Address>,
#[serde(default)]
pub sub_deployers: Vec<(String, Vec<Address>)>,
#[serde(default)]
pub asset_to_streaming_oi_cap: Vec<(String, Dec)>,
#[serde(default)]
pub asset_to_funding_multiplier: Vec<(String, Dec)>,
#[serde(default)]
pub asset_to_funding_interest_rate: Vec<(String, Dec)>,
#[serde(default)]
pub asset_to_funding_clamp: Vec<(String, Dec)>,
}
impl PerpDex {
#[must_use]
pub fn streaming_oi_cap(&self, coin: &str) -> Option<Dec> {
lookup(&self.asset_to_streaming_oi_cap, coin)
}
#[must_use]
pub fn funding_multiplier(&self, coin: &str) -> Option<Dec> {
lookup(&self.asset_to_funding_multiplier, coin)
}
#[must_use]
pub fn funding_interest_rate(&self, coin: &str) -> Option<Dec> {
lookup(&self.asset_to_funding_interest_rate, coin)
}
#[must_use]
pub fn funding_clamp(&self, coin: &str) -> Option<Dec> {
lookup(&self.asset_to_funding_clamp, coin)
}
#[must_use]
pub fn sub_deployers_for(&self, action: &str) -> &[Address] {
self.sub_deployers.iter().find(|(listed, _)| listed == action).map_or(&[], |(_, users)| users.as_slice())
}
}
fn lookup(pairs: &[(String, Dec)], coin: &str) -> Option<Dec> {
pairs.iter().find(|(listed, _)| listed == coin).map(|(_, value)| *value)
}