use serde::{Deserialize, Serialize};
use crate::types::MarketId;
use crate::wallet::Address;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct Position {
pub owner: Address,
pub market: MarketId,
pub size: i64,
pub entry_px: u64,
pub unrealised_pnl_cents: i64,
pub margin_cents: u64,
pub funding_paid_cents: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct UserState {
pub address: Address,
pub account_value_cents: i64,
pub total_unrealised_pnl_cents: i64,
pub position_count: u32,
pub positions: Vec<Position>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn position_serializes_snake_case() {
let p = Position {
owner: Address::ZERO,
market: MarketId(1),
size: -500,
entry_px: 4_999_500_000_000,
unrealised_pnl_cents: 1234,
margin_cents: 500_000,
funding_paid_cents: -42,
};
let j = serde_json::to_value(&p).unwrap();
for key in [
"entry_px",
"unrealised_pnl_cents",
"margin_cents",
"funding_paid_cents",
] {
assert!(j.get(key).is_some(), "missing snake_case key {key}");
}
}
#[test]
fn user_state_serializes_account_value_as_cents() {
let u = UserState {
address: Address::ZERO,
account_value_cents: 10_000_000, total_unrealised_pnl_cents: -2_500,
position_count: 0,
positions: vec![],
};
let j = serde_json::to_value(&u).unwrap();
assert_eq!(j["account_value_cents"], 10_000_000);
}
}