use serde::{Deserialize, Serialize};
use crate::types::MarketId;
use crate::types::rfq::CoreSide;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct FbaConfig {
pub period_ms: u32,
pub min_lot: u64,
pub next_auction_at_ms: u64,
pub enabled: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct FbaBatchResult {
pub batch_id: u64,
pub market: MarketId,
pub clearing_px: u64,
pub volume: u64,
pub closed_at_ms: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct FbaSubmit {
pub market: MarketId,
pub side: CoreSide,
pub size: u128,
pub price: i128,
pub stp_group: Option<u64>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fba_submit_uses_price_pascalcase_side_and_present_stp() {
let s = FbaSubmit {
market: MarketId(7),
side: CoreSide::Ask,
size: 1_000,
price: 5_000_000_000,
stp_group: None,
};
let j = serde_json::to_value(s).unwrap();
assert_eq!(j["side"], "Ask");
assert!(j.get("price").is_some());
assert!(j.get("limit_px").is_none());
assert!(j.get("stp_group").is_some() && j["stp_group"].is_null());
let dec: FbaSubmit = serde_json::from_value(j).unwrap();
assert_eq!(dec, s);
}
#[test]
fn fba_config_round_trips() {
let c = FbaConfig {
period_ms: 250,
min_lot: 5,
next_auction_at_ms: 1_700_000_001_000,
enabled: true,
};
let j = serde_json::to_string(&c).unwrap();
let dec: FbaConfig = serde_json::from_str(&j).unwrap();
assert_eq!(c, dec);
}
#[test]
fn batch_result_has_clearing_px_field() {
let r = FbaBatchResult {
batch_id: 1,
market: MarketId(1),
clearing_px: 5_000_000_000_000,
volume: 1000,
closed_at_ms: 1_700_000_002_000,
};
let j = serde_json::to_value(&r).unwrap();
assert!(j.get("clearing_px").is_some());
}
}