bullet_ws_interface/
response.rs1use serde::{Deserialize, Serialize};
5
6use crate::RequestId;
7
8#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)]
11#[serde(rename_all = "lowercase")]
12pub enum TxStatus {
13 Processed,
15 Published,
17 Submitted,
19 Finalized,
21 Dropped,
23 #[serde(other)]
25 Unknown,
26}
27
28impl TxStatus {
29 #[must_use]
33 pub fn is_success(self) -> bool {
34 matches!(self, Self::Processed | Self::Published | Self::Submitted | Self::Finalized)
35 }
36}
37
38#[derive(Serialize, Deserialize, Clone, Debug)]
40pub struct OrderResultPayload {
41 pub tx_id: String,
43 pub status: TxStatus,
45 #[serde(default)]
48 pub order_ids: Vec<u64>,
49 #[serde(default)]
51 pub client_order_ids: Vec<u64>,
52}
53
54#[derive(Serialize, Deserialize, Clone, Debug)]
57pub struct OrderResultMessage {
58 pub id: Option<RequestId>,
59 #[serde(rename = "E")]
61 pub event_time: u64,
62 pub results: OrderResultPayload,
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn round_trip_full_payload() {
71 let json = r#"{
72 "id": 42,
73 "E": 1706745600000000,
74 "results": {
75 "tx_id": "0xabc123",
76 "status": "processed",
77 "order_ids": [1, 2],
78 "client_order_ids": [100, 101]
79 }
80 }"#;
81 let msg: OrderResultMessage = serde_json::from_str(json).unwrap();
82 assert_eq!(msg.id, Some(RequestId::from(42u64)));
83 assert_eq!(msg.event_time, 1_706_745_600_000_000);
84 assert_eq!(msg.results.tx_id, "0xabc123");
85 assert_eq!(msg.results.status, TxStatus::Processed);
86 assert_eq!(msg.results.order_ids, vec![1, 2]);
87 assert_eq!(msg.results.client_order_ids, vec![100, 101]);
88 }
89
90 #[test]
91 fn id_absent_defaults_to_none() {
92 let json = r#"{"E":1706745600000000,"results":{"tx_id":"0x1","status":"submitted"}}"#;
94 let msg: OrderResultMessage = serde_json::from_str(json).unwrap();
95 assert_eq!(msg.id, None);
96 }
97
98 #[test]
99 fn optional_vec_fields_absent() {
100 let json = r#"{"id":1,"E":1706745600000000,"results":{"tx_id":"0x2","status":"processed","order_ids":[5]}}"#;
102 let msg: OrderResultMessage = serde_json::from_str(json).unwrap();
103 assert!(msg.results.client_order_ids.is_empty());
104 }
105
106 #[test]
107 fn unknown_status_is_catch_all() {
108 let json = r#"{"id":1,"E":0,"results":{"tx_id":"0x1","status":"pending"}}"#;
111 let msg: OrderResultMessage = serde_json::from_str(json).unwrap();
112 assert_eq!(msg.results.status, TxStatus::Unknown);
113 assert!(!msg.results.status.is_success());
114 }
115
116 #[test]
117 fn tx_status_is_success() {
118 assert!(TxStatus::Processed.is_success());
119 assert!(TxStatus::Published.is_success());
120 assert!(TxStatus::Submitted.is_success());
121 assert!(TxStatus::Finalized.is_success());
122 assert!(!TxStatus::Dropped.is_success());
123 assert!(!TxStatus::Unknown.is_success());
124 }
125}