use serde::Deserialize;
use serde_json::value::RawValue;
use crate::live::frame::fields::{blank, raw_text};
use crate::utils::ids::whole;
use crate::utils::{AccountIndex, Dec, Figure, MarketId};
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct LiquidationNote {
#[serde(default)]
pub id: String,
pub is_ask: bool,
pub usdc_amount: Dec,
pub size: Dec,
pub market_index: MarketId,
pub price: Dec,
#[serde(default, deserialize_with = "whole")]
pub timestamp: u64,
#[serde(default, deserialize_with = "blank")]
pub avg_price: Option<Dec>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct DeleverageNote {
#[serde(default)]
pub id: String,
pub usdc_amount: Dec,
pub size: Dec,
pub market_index: MarketId,
pub settlement_price: Dec,
#[serde(default, deserialize_with = "whole")]
pub timestamp: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Announcement {
pub title: String,
pub content: String,
#[serde(default, deserialize_with = "whole")]
pub created_at: u64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NoteContent {
Liquidation(LiquidationNote),
Deleverage(DeleverageNote),
Announcement(Announcement),
Other(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(from = "RawNote")]
pub struct Notification {
pub id: String,
pub created_at: String,
pub updated_at: String,
pub kind: String,
pub account_index: AccountIndex,
pub content: NoteContent,
pub ack: bool,
pub acked_at: Option<String>,
}
#[derive(Deserialize)]
struct RawNote {
#[serde(default)]
id: String,
#[serde(default)]
created_at: String,
#[serde(default)]
updated_at: String,
kind: String,
account_index: AccountIndex,
content: Box<RawValue>,
#[serde(default)]
ack: bool,
#[serde(default)]
acked_at: Option<String>,
}
impl From<RawNote> for Notification {
fn from(raw: RawNote) -> Self {
let text = raw.content.get();
let content = match raw.kind.as_str() {
"liquidation" => serde_json::from_str(text).map(NoteContent::Liquidation).ok(),
"deleverage" => serde_json::from_str(text).map(NoteContent::Deleverage).ok(),
"announcement" => serde_json::from_str(text).map(NoteContent::Announcement).ok(),
_ => None,
};
Notification {
id: raw.id,
created_at: raw.created_at,
updated_at: raw.updated_at,
content: content.unwrap_or_else(|| NoteContent::Other(text.to_owned())),
kind: raw.kind,
account_index: raw.account_index,
ack: raw.ack,
acked_at: raw.acked_at,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Notifications {
pub account: AccountIndex,
pub notes: Vec<Notification>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Rfq {
#[serde(deserialize_with = "whole")]
pub id: u64,
pub account_index: AccountIndex,
pub market_index: MarketId,
pub direction: i8,
#[serde(default, deserialize_with = "blank")]
pub base_amount: Option<Dec>,
#[serde(default, deserialize_with = "blank")]
pub quote_amount: Option<Dec>,
pub status: String,
#[serde(default, deserialize_with = "raw_text")]
pub metadata: String,
#[serde(default, deserialize_with = "raw_text")]
pub responses: String,
#[serde(default, deserialize_with = "whole")]
pub created_at: u64,
#[serde(default, deserialize_with = "whole")]
pub updated_at: u64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LivePoints {
pub account: AccountIndex,
pub total: Figure,
}