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