ibapi/trace/async.rs
1use crate::trace::common::{storage::async_ops, Interaction};
2
3/// Gets the last interaction with the server, if any
4///
5/// Returns `None` if no interactions have been recorded yet.
6///
7/// # Example
8/// ```no_run
9/// use ibapi::trace;
10///
11/// # async fn example() {
12/// if let Some(interaction) = trace::last_interaction().await {
13/// println!("Last request: {}", interaction.request);
14/// println!("Responses: {:?}", interaction.responses);
15/// }
16/// # }
17/// ```
18pub async fn last_interaction() -> Option<Interaction> {
19 async_ops::get_last_interaction().await.map(|arc| (*arc).clone())
20}
21
22/// Records a new request, starting a new interaction
23///
24/// This function starts tracking a new server interaction. Any subsequent
25/// calls to `record_response` will add responses to this interaction until
26/// a new request is recorded.
27///
28/// # Arguments
29/// * `message` - The request message being sent to the server
30///
31/// # Example
32/// ```no_run
33/// use ibapi::trace;
34///
35/// # async fn example() {
36/// trace::record_request("REQ|123|AAPL|".to_string()).await;
37/// # }
38/// ```
39pub async fn record_request(message: String) {
40 async_ops::start_new_interaction(message).await;
41}
42
43/// Records a response message for the current interaction
44///
45/// Adds a response to the most recent interaction started by `record_request`.
46/// If no interaction has been started, this function does nothing.
47///
48/// # Arguments
49/// * `message` - The response message received from the server
50///
51/// # Example
52/// ```no_run
53/// use ibapi::trace;
54///
55/// # async fn example() {
56/// trace::record_request("REQ|123|AAPL|".to_string()).await;
57/// trace::record_response("RESP|123|150.00|".to_string()).await;
58/// trace::record_response("RESP|123|151.00|".to_string()).await;
59/// # }
60/// ```
61pub async fn record_response(message: String) {
62 async_ops::add_response_to_current(message).await;
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::trace::common::storage::async_ops;
69 use serial_test::serial;
70
71 #[tokio::test]
72 #[serial]
73 async fn test_no_interaction_initially() {
74 // Clear to ensure clean initial state
75 async_ops::clear().await;
76 assert!(last_interaction().await.is_none());
77 }
78
79 #[tokio::test]
80 #[serial]
81 async fn test_record_and_retrieve_interaction() {
82 // Record a request - this replaces any previous interaction
83 record_request("TEST_REQUEST".to_string()).await;
84
85 // Should be able to get it back
86 let interaction = last_interaction().await.expect("Should have interaction");
87 assert_eq!(interaction.request, "TEST_REQUEST");
88 assert_eq!(interaction.responses.len(), 0);
89 }
90
91 #[tokio::test]
92 #[serial]
93 async fn test_record_request_and_responses() {
94 // Record a request - this replaces any previous interaction
95 record_request("REQUEST_1".to_string()).await;
96
97 // Record some responses
98 record_response("RESPONSE_1".to_string()).await;
99 record_response("RESPONSE_2".to_string()).await;
100
101 // Check the interaction
102 let interaction = last_interaction().await.expect("Should have interaction");
103 assert_eq!(interaction.request, "REQUEST_1");
104 assert_eq!(interaction.responses.len(), 2);
105 assert_eq!(interaction.responses[0], "RESPONSE_1");
106 assert_eq!(interaction.responses[1], "RESPONSE_2");
107 }
108
109 #[tokio::test]
110 #[serial]
111 async fn test_new_request_replaces_old() {
112 // First interaction
113 record_request("REQUEST_1".to_string()).await;
114 record_response("RESPONSE_1".to_string()).await;
115
116 // Second interaction - this replaces the first
117 record_request("REQUEST_2".to_string()).await;
118 record_response("RESPONSE_2".to_string()).await;
119
120 // Should only have the second interaction
121 let interaction = last_interaction().await.expect("Should have interaction");
122 assert_eq!(interaction.request, "REQUEST_2");
123 assert_eq!(interaction.responses.len(), 1);
124 assert_eq!(interaction.responses[0], "RESPONSE_2");
125 }
126}