use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct ProtocolResponse {
#[serde(default)]
pub tvl: Vec<TvlSnapshot>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct LiteResponse {
#[serde(default)]
pub protocols: Vec<LiteProtocol>,
#[serde(default, rename = "parentProtocols")]
pub parent_protocols: Vec<LiteParent>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct LiteProtocol {
#[serde(default)]
pub name: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub url: Option<String>,
#[serde(default)]
pub chains: Vec<String>,
#[serde(default, rename = "chainTvls")]
pub chain_tvls: HashMap<String, LiteChainTvl>,
#[serde(default)]
pub tvl: Option<f64>,
#[serde(default, rename = "tvlPrevDay")]
pub tvl_prev_day: Option<f64>,
#[serde(default, rename = "tvlPrevWeek")]
pub tvl_prev_week: Option<f64>,
#[serde(default)]
pub mcap: Option<f64>,
#[serde(default, rename = "parentProtocol")]
pub parent_protocol: Option<String>,
#[serde(default, rename = "excludeTvlFromParent")]
pub exclude_tvl_from_parent: bool,
#[serde(default)]
pub deprecated: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct LiteChainTvl {
#[serde(default)]
pub tvl: f64,
#[serde(default, rename = "tvlPrevDay")]
pub tvl_prev_day: Option<f64>,
#[serde(default, rename = "tvlPrevWeek")]
pub tvl_prev_week: Option<f64>,
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum Period {
Now,
Day,
Week,
}
impl LiteProtocol {
pub fn tvl_at(&self, period: Period) -> Option<f64> {
match period {
Period::Now => self.tvl,
Period::Day => self.tvl_prev_day,
Period::Week => self.tvl_prev_week,
}
}
}
impl LiteChainTvl {
pub fn tvl_at(&self, period: Period) -> Option<f64> {
match period {
Period::Now => Some(self.tvl),
Period::Day => self.tvl_prev_day,
Period::Week => self.tvl_prev_week,
}
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct LiteParent {
pub id: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub url: Option<String>,
#[serde(default)]
pub chains: Vec<String>,
#[serde(default)]
pub mcap: Option<f64>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct TvlSnapshot {
pub date: i64,
#[serde(rename = "totalLiquidityUSD")]
pub total_liquidity_usd: f64,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct ChainResponse {
pub name: String,
#[serde(default, rename = "tokenSymbol")]
pub token_symbol: Option<String>,
#[serde(default)]
pub gecko_id: Option<String>,
#[serde(default, rename = "chainId", deserialize_with = "lenient_chain_id")]
pub chain_id: Option<i64>,
#[serde(default)]
pub tvl: Option<f64>,
}
fn lenient_chain_id<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum ChainId {
Int(i64),
Text(String),
}
Ok(match Option::<ChainId>::deserialize(deserializer)? {
Some(ChainId::Int(id)) => Some(id),
Some(ChainId::Text(id)) => id.parse().ok(),
None => None,
})
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct StablecoinsResponse {
#[serde(default, rename = "peggedAssets")]
pub pegged_assets: Vec<PeggedAsset>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct PeggedAsset {
pub name: String,
#[serde(default)]
pub symbol: Option<String>,
#[serde(default)]
pub gecko_id: Option<String>,
#[serde(default, rename = "pegType")]
pub peg_type: Option<String>,
#[serde(default, rename = "pegMechanism")]
pub peg_mechanism: Option<String>,
#[serde(default)]
pub circulating: HashMap<String, f64>,
#[serde(default, rename = "circulatingPrevDay")]
pub circulating_prev_day: HashMap<String, f64>,
#[serde(default, rename = "circulatingPrevWeek")]
pub circulating_prev_week: HashMap<String, f64>,
#[serde(default, rename = "circulatingPrevMonth")]
pub circulating_prev_month: HashMap<String, f64>,
}