use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use super::{Symbol, option_timestamp_ms};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TraderInfo {
#[serde(default)]
pub accounts: Vec<String>,
#[serde(rename = "isLive")]
pub is_live: bool,
#[serde(rename = "traderId")]
pub trader_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UserInfo {
#[serde(rename = "accountCategory", default)]
pub account_category: Option<i32>,
#[serde(rename = "accountTitle", default)]
pub account_title: Option<String>,
#[serde(rename = "emailAddress1", default)]
pub email_address_1: Option<String>,
#[serde(rename = "emailAddress2", default)]
pub email_address_2: Option<String>,
#[serde(default)]
pub group: Option<String>,
#[serde(rename = "isClearingAccount", default)]
pub is_clearing_account: Option<bool>,
#[serde(default)]
pub phone1: Option<String>,
#[serde(default)]
pub phone2: Option<String>,
#[serde(rename = "subGroup", default)]
pub sub_group: Option<String>,
#[serde(default)]
pub accounts: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SymbolInfo {
pub symbol: Symbol,
#[serde(default)]
pub currency: Option<String>,
#[serde(default)]
pub description: Option<String>,
#[serde(rename = "hasQuotes", default)]
pub has_quotes: Option<bool>,
#[serde(rename = "pipValue", default)]
pub pip_value: Option<f64>,
#[serde(rename = "pipSize", default)]
pub pip_size: Option<f64>,
#[serde(rename = "minTick", default)]
pub min_tick: Option<f64>,
#[serde(rename = "qtyStep", default)]
pub qty_step: Option<f64>,
#[serde(rename = "symbolType", default)]
pub symbol_type: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FutureInfo {
pub symbol: Symbol,
#[serde(rename = "maturityMonth", default)]
pub maturity_month: Option<String>,
#[serde(rename = "maturityYear", default)]
pub maturity_year: Option<i32>,
#[serde(default)]
pub description: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ComplexGroups {
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub groups: Vec<ComplexGroupInfo>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ComplexGroupInfo {
#[serde(default)]
pub group: Option<String>,
#[serde(default)]
pub name: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OptionGroupInfo {
#[serde(default)]
pub group: Option<String>,
#[serde(default, with = "option_timestamp_ms")]
pub expiration: Option<OffsetDateTime>,
#[serde(default)]
pub description: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SymbolOptionsResult {
pub groups: Vec<String>,
pub option_groups: Vec<OptionGroupInfo>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn trader_info_deserialize() {
let json = r#"{"accounts":["ACC001","ACC002"],"isLive":true,"traderId":"T001"}"#;
let t: TraderInfo = serde_json::from_str(json).unwrap();
assert_eq!(t.accounts.len(), 2);
assert!(t.is_live);
}
#[test]
fn symbol_info_deserialize() {
let json = r#"{
"symbol": "XCME:ES.U16",
"currency": "USD",
"symbolType": "Future",
"pipValue": 12.5
}"#;
let s: SymbolInfo = serde_json::from_str(json).unwrap();
assert_eq!(s.symbol, "XCME:ES.U16");
assert_eq!(s.symbol_type.as_deref(), Some("Future"));
}
}