Skip to main content

nautilus_model/events/order/
canceled_batch.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::fmt::{Debug, Display};
17
18use super::canceled::OrderCanceled;
19
20/// Represents a batch of [`OrderCanceled`] events from a single cancel-all
21/// or batch-cancel response. Transported as one message across the event loop,
22/// then unpacked into individual [`OrderCanceled`] events for processing.
23#[derive(Clone, PartialEq, Eq)]
24pub struct OrderCanceledBatch {
25    pub events: Vec<OrderCanceled>,
26}
27
28impl OrderCanceledBatch {
29    /// Creates a new [`OrderCanceledBatch`] instance.
30    #[must_use]
31    pub fn new(events: Vec<OrderCanceled>) -> Self {
32        Self { events }
33    }
34
35    /// Returns the number of events in the batch.
36    #[must_use]
37    pub fn len(&self) -> usize {
38        self.events.len()
39    }
40
41    /// Returns whether the batch is empty.
42    #[must_use]
43    pub fn is_empty(&self) -> bool {
44        self.events.is_empty()
45    }
46}
47
48impl Debug for OrderCanceledBatch {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        f.debug_struct(stringify!(OrderCanceledBatch))
51            .field("len", &self.events.len())
52            .finish()
53    }
54}
55
56impl Display for OrderCanceledBatch {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(
59            f,
60            "{}(len={})",
61            stringify!(OrderCanceledBatch),
62            self.events.len()
63        )
64    }
65}
66
67impl IntoIterator for OrderCanceledBatch {
68    type Item = OrderCanceled;
69    type IntoIter = std::vec::IntoIter<OrderCanceled>;
70
71    fn into_iter(self) -> Self::IntoIter {
72        self.events.into_iter()
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use rstest::rstest;
79
80    use super::*;
81
82    #[rstest]
83    fn test_empty_batch() {
84        let batch = OrderCanceledBatch::new(Vec::new());
85        assert!(batch.is_empty());
86        assert_eq!(batch.len(), 0);
87    }
88
89    #[rstest]
90    fn test_batch_with_events() {
91        let events = vec![OrderCanceled::default(), OrderCanceled::default()];
92        let batch = OrderCanceledBatch::new(events);
93        assert!(!batch.is_empty());
94        assert_eq!(batch.len(), 2);
95    }
96
97    #[rstest]
98    fn test_debug_display() {
99        let batch = OrderCanceledBatch::new(vec![OrderCanceled::default()]);
100        assert_eq!(format!("{batch}"), "OrderCanceledBatch(len=1)");
101        assert_eq!(format!("{batch:?}"), "OrderCanceledBatch { len: 1 }");
102    }
103
104    #[rstest]
105    fn test_into_iter() {
106        let events = vec![OrderCanceled::default(), OrderCanceled::default()];
107        let batch = OrderCanceledBatch::new(events);
108        assert_eq!(batch.into_iter().count(), 2);
109    }
110}