use pretty_simple_display::{DebugPretty, DisplaySimple};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, PartialEq, Serialize, Deserialize)]
pub struct TriggerOrderHistoryEntry {
pub timestamp: i64,
pub trigger: Option<String>,
pub trigger_price: Option<f64>,
pub trigger_offset: Option<f64>,
pub trigger_order_id: String,
pub order_id: Option<String>,
pub order_state: String,
pub instrument_name: String,
pub request: Option<String>,
pub direction: String,
pub price: Option<f64>,
pub amount: f64,
pub reduce_only: Option<bool>,
pub post_only: Option<bool>,
pub order_type: Option<String>,
pub label: Option<String>,
pub linked_order_type: Option<String>,
pub oco_ref: Option<String>,
pub trigger_source: Option<String>,
pub last_update_timestamp: Option<i64>,
}
#[skip_serializing_none]
#[derive(DebugPretty, DisplaySimple, Clone, PartialEq, Serialize, Deserialize)]
pub struct TriggerOrderHistoryResponse {
pub entries: Vec<TriggerOrderHistoryEntry>,
pub continuation: Option<String>,
}
impl TriggerOrderHistoryResponse {
pub fn new(entries: Vec<TriggerOrderHistoryEntry>) -> Self {
Self {
entries,
continuation: None,
}
}
pub fn with_continuation(entries: Vec<TriggerOrderHistoryEntry>, continuation: String) -> Self {
Self {
entries,
continuation: Some(continuation),
}
}
pub fn has_more(&self) -> bool {
self.continuation.is_some()
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl Default for TriggerOrderHistoryResponse {
fn default() -> Self {
Self::new(Vec::new())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trigger_order_history_response_new() {
let response = TriggerOrderHistoryResponse::new(vec![]);
assert!(response.entries.is_empty());
assert!(response.continuation.is_none());
assert!(!response.has_more());
}
#[test]
fn test_trigger_order_history_response_with_continuation() {
let response =
TriggerOrderHistoryResponse::with_continuation(vec![], "token123".to_string());
assert!(response.entries.is_empty());
assert_eq!(response.continuation, Some("token123".to_string()));
assert!(response.has_more());
}
#[test]
fn test_trigger_order_history_entry_deserialization() {
let json = r#"{
"timestamp": 1555918941451,
"trigger": "index_price",
"trigger_price": 5285.0,
"trigger_order_id": "SLIS-103",
"order_id": "671473",
"order_state": "triggered",
"instrument_name": "BTC-PERPETUAL",
"request": "trigger:order",
"direction": "buy",
"price": 5179.28,
"amount": 10.0
}"#;
let entry: TriggerOrderHistoryEntry = serde_json::from_str(json).unwrap();
assert_eq!(entry.timestamp, 1555918941451);
assert_eq!(entry.trigger, Some("index_price".to_string()));
assert_eq!(entry.trigger_price, Some(5285.0));
assert_eq!(entry.trigger_order_id, "SLIS-103");
assert_eq!(entry.order_id, Some("671473".to_string()));
assert_eq!(entry.order_state, "triggered");
assert_eq!(entry.instrument_name, "BTC-PERPETUAL");
assert_eq!(entry.direction, "buy");
assert_eq!(entry.amount, 10.0);
}
}