use serde::{
Deserialize,
Serialize,
};
use crate::deserialization::{
iso_date_time,
string_as_float,
};
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type")]
#[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))]
#[non_exhaustive]
pub enum WebsocketMessage {
Subscribe(SubscribeRequest),
Heartbeat(HeartbeatMessage),
Subscriptions(SubscriptionsMessage),
Status(StatusMessage),
Ticker(TickerMessage),
Snapshot(Level2Snapshot),
L2Update(Level2Update),
Received(ReceivedMessage),
Open(OpenMessage),
Match(MatchMessage),
Done(DoneMessage),
Change(ChangeMessage),
Activate(ActivateMessage),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "name")]
#[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))]
#[non_exhaustive]
pub enum Channel {
Heartbeat(HeartbeatChannel),
Status(StatusChannel),
Ticker(TickerChannel),
Level2(Level2Channel),
Full(FullChannel),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SubscribeRequest {
pub channels: Vec<Channel>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct SubscriptionsMessage {
pub channels: Vec<Channel>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HeartbeatChannel {
pub product_ids: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level2Channel {
pub product_ids: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TickerChannel {
pub product_ids: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FullChannel {
pub product_ids: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StatusChannel {}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StatusMessage {
pub products: Vec<StatusProduct>,
pub currencies: Vec<StatusCurrency>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StatusProduct {
pub id: String,
pub base_currency: String,
pub quote_currency: String,
#[serde(with = "string_as_float")]
pub base_min_size: f64,
#[serde(with = "string_as_float")]
pub base_max_size: f64,
#[serde(with = "string_as_float")]
pub base_increment: f64,
#[serde(with = "string_as_float")]
pub quote_increment: f64,
pub display_name: String,
pub status: String,
pub status_message: Option<String>,
#[serde(with = "string_as_float")]
pub min_market_funds: f64,
#[serde(with = "string_as_float")]
pub max_market_funds: f64,
pub post_only: bool,
pub limit_only: bool,
pub cancel_only: bool,
pub fx_stablecoin: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StatusCurrency {
pub id: String,
pub name: String,
#[serde(with = "string_as_float")]
pub min_size: f64,
pub status: String,
pub status_messag: Option<String>,
#[serde(with = "string_as_float")]
pub max_precision: f64,
pub convertible_to: Vec<String>,
pub details: StatusDetails,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "type")]
#[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))]
pub enum StatusDetails {
Crypto(CryptoDetails),
Fiat(FiatDetails),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CryptoDetails {
pub symbol: String,
pub network_confirmations: u64,
pub sort_order: u64,
pub crypto_address_link: String,
pub crypto_transaction_link: String,
pub push_payment_methods: Vec<String>,
pub min_withdrawal_amount: f64,
pub max_withdrawal_amount: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct FiatDetails {
pub symbol: String,
pub network_confirmations: u64,
pub sort_order: u64,
pub crypto_address_link: String,
pub crypto_transaction_link: String,
pub push_payment_methods: Vec<String>,
pub group_types: Vec<String>,
pub display_name: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct HeartbeatMessage {
pub sequence: u64,
pub last_trade_id: u64,
pub product_id: String,
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TickerMessage {
pub trade_id: u64,
pub sequence: u64,
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub product_id: String,
#[serde(with = "string_as_float")]
pub price: f64,
pub side: String,
#[serde(with = "string_as_float")]
pub last_size: f64,
#[serde(with = "string_as_float")]
pub best_bid: f64,
#[serde(with = "string_as_float")]
pub best_ask: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level2Snapshot {
pub product_id: String,
pub bids: Vec<Quote>,
pub asks: Vec<Quote>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level2Update {
pub product_id: String,
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub changes: Vec<Level2Change>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Level2Change {
pub side: String,
#[serde(with = "string_as_float")]
pub price: f64,
#[serde(with = "string_as_float")]
pub size: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ReceivedMessage {
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub product_id: String,
pub sequence: u64,
pub order_id: String,
#[serde(flatten)]
pub order: Order,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(tag = "order_type")]
#[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))]
pub enum Order {
Limit(LimitOrder),
Market(MarketOrder),
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct LimitOrder {
#[serde(with = "string_as_float")]
pub size: f64,
#[serde(with = "string_as_float")]
pub price: f64,
pub side: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MarketOrder {
#[serde(default)]
#[serde(with = "string_as_float")]
pub funds: f64,
pub side: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct OpenMessage {
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub product_id: String,
pub sequence: u64,
pub order_id: String,
#[serde(with = "string_as_float")]
pub price: f64,
#[serde(with = "string_as_float")]
pub remaining_size: f64,
pub side: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DoneMessage {
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub product_id: String,
pub sequence: u64,
#[serde(default)]
#[serde(with = "string_as_float")]
pub price: f64,
pub order_id: String,
pub reason: String, pub side: String,
#[serde(default)]
#[serde(with = "string_as_float")]
pub remaining_size: f64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MatchMessage {
pub trade_id: u64,
pub sequence: u64,
pub maker_order_id: String,
pub taker_order_id: String,
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub product_id: String,
#[serde(with = "string_as_float")]
pub size: f64,
#[serde(with = "string_as_float")]
pub price: f64,
pub side: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ChangeMessage {
#[serde(with = "iso_date_time")]
pub time: chrono::NaiveDateTime,
pub sequence: u64,
pub order_id: String,
pub product_id: String,
#[serde(with = "string_as_float")]
pub new_size: f64,
#[serde(with = "string_as_float")]
pub old_size: f64,
#[serde(with = "string_as_float")]
pub price: f64,
pub side: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ActivateMessage {
pub product_id: String,
pub timestamp: String,
pub user_id: String,
pub profile_id: String,
pub order_id: String,
pub stop_type: String,
pub side: String,
#[serde(with = "string_as_float")]
pub stop_price: f64,
#[serde(with = "string_as_float")]
pub size: f64,
#[serde(with = "string_as_float")]
pub funds: f64,
pub private: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Quote {
#[serde(with = "string_as_float")]
price: f64,
#[serde(with = "string_as_float")]
size: f64,
}