use std::fmt;
use serde::{Deserialize, Deserializer, de};
use crate::utils::dec::Dec;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Mids(Vec<(String, Dec)>);
impl Mids {
#[must_use]
pub fn get(&self, coin: &str) -> Option<Dec> {
self.0.iter().find(|(name, _)| name == coin).map(|(_, mid)| *mid)
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (&str, Dec)> {
self.0.iter().map(|(coin, mid)| (coin.as_str(), *mid))
}
}
impl FromIterator<(String, Dec)> for Mids {
fn from_iter<I: IntoIterator<Item = (String, Dec)>>(pairs: I) -> Self {
Mids(pairs.into_iter().collect())
}
}
impl<'de> Deserialize<'de> for Mids {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct Pairs;
impl<'de> de::Visitor<'de> for Pairs {
type Value = Mids;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a map of coin to price")
}
fn visit_map<A: de::MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
let mut out = Vec::with_capacity(map.size_hint().unwrap_or(0));
while let Some(pair) = map.next_entry::<String, Dec>()? {
out.push(pair);
}
Ok(Mids(out))
}
}
deserializer.deserialize_map(Pairs)
}
}
#[cfg(test)]
#[path = "tests/mids.rs"]
mod tests;