batch_mode_batch_schema/
batch_error_data.rs

1// ---------------- [ File: batch-mode-batch-schema/src/batch_error_data.rs ]
2crate::ix!();
3
4#[derive(Serialize,Deserialize,Getters,Builder,Clone,Debug)]
5#[builder(setter(into))]
6#[getset(get="pub")]
7pub struct BatchErrorData {
8    responses: Vec<BatchResponseRecord>,
9}
10
11impl BatchErrorData {
12
13    pub fn len(&self) -> usize {
14        self.responses.len()
15    }
16
17    pub fn new(responses: Vec<BatchResponseRecord>) -> Self {
18        Self { responses }
19    }
20
21    pub fn request_ids(&self) -> Vec<CustomRequestId> {
22        self.responses.iter().map(|r| r.custom_id().clone()).collect()
23    }
24
25    /// Returns an iterator over the BatchResponseRecord elements.
26    pub fn iter(&self) -> std::slice::Iter<BatchResponseRecord> {
27        self.responses.iter()
28    }
29}
30
31impl<'a> IntoIterator for &'a BatchErrorData {
32    type Item = &'a BatchResponseRecord;
33    type IntoIter = std::slice::Iter<'a, BatchResponseRecord>;
34
35    fn into_iter(self) -> Self::IntoIter {
36        self.responses.iter()
37    }
38}
39
40impl IntoIterator for BatchErrorData {
41    type Item = BatchResponseRecord;
42    type IntoIter = std::vec::IntoIter<BatchResponseRecord>;
43
44    fn into_iter(self) -> Self::IntoIter {
45        self.responses.into_iter()
46    }
47}
48
49impl From<Vec<BatchErrorData>> for BatchErrorData {
50    fn from(batch_errors: Vec<BatchErrorData>) -> Self {
51        // Flatten the responses from all BatchErrorData instances into a single vector.
52        let aggregated_responses = batch_errors
53            .into_iter()
54            .flat_map(|error_data| error_data.responses)
55            .collect();
56        BatchErrorData::new(aggregated_responses)
57    }
58}
59
60#[cfg(test)]
61mod batch_error_data_tests {
62    use super::*;
63
64    #[traced_test]
65    fn should_create_new_batch_error_data() {
66        info!("Testing creation of BatchErrorData with 'new' function.");
67
68        let records = vec![
69            BatchResponseRecord::mock("id-1"),
70            BatchResponseRecord::mock("id-2"),
71        ];
72        let error_data = BatchErrorData::new(records.clone());
73
74        pretty_assert_eq!(error_data.len(), 2, "Expected error_data to have length 2.");
75        pretty_assert_eq!(error_data.responses().len(), 2, "Responses vector should match length 2.");
76        debug!("Created BatchErrorData with {} entries.", error_data.len());
77    }
78
79    #[traced_test]
80    fn should_return_request_ids_correctly() {
81        info!("Testing retrieval of request IDs from BatchErrorData.");
82
83        let records = vec![
84            BatchResponseRecord::mock("custom-1"),
85            BatchResponseRecord::mock("custom-2"),
86        ];
87        let error_data = BatchErrorData::new(records);
88
89        let ids = error_data.request_ids();
90        trace!("Extracted request IDs: {:?}", ids);
91
92        pretty_assert_eq!(ids.len(), 2, "Should have exactly 2 IDs.");
93        assert!(ids.contains(&CustomRequestId::new("custom-1")));
94        assert!(ids.contains(&CustomRequestId::new("custom-2")));
95    }
96
97    #[traced_test]
98    fn should_provide_iter_over_responses() {
99        info!("Testing iteration over BatchErrorData responses.");
100
101        let records = vec![
102            BatchResponseRecord::mock("iter-1"),
103            BatchResponseRecord::mock("iter-2"),
104        ];
105        let error_data = BatchErrorData::new(records.clone());
106
107        let mut iter_count = 0;
108        for (index, record) in error_data.iter().enumerate() {
109            trace!("Iterating index: {}, record.custom_id: {}", index, record.custom_id());
110            iter_count += 1;
111        }
112        pretty_assert_eq!(iter_count, records.len(), "Iterator should cover all responses.");
113    }
114
115    #[traced_test]
116    fn should_iterate_with_into_iter_borrowed() {
117        info!("Testing the IntoIterator for borrowed BatchErrorData.");
118
119        let records = vec![
120            BatchResponseRecord::mock("borrow-1"),
121            BatchResponseRecord::mock("borrow-2"),
122        ];
123        let error_data = BatchErrorData::new(records.clone());
124
125        let mut iter_count = 0;
126        for record in &error_data {
127            trace!("Borrowed iteration item: {:?}", record.custom_id());
128            iter_count += 1;
129        }
130        pretty_assert_eq!(iter_count, records.len(), "Borrowed iterator should cover all responses.");
131    }
132
133    #[traced_test]
134    fn should_iterate_with_into_iter_owned() {
135        info!("Testing the IntoIterator for owned BatchErrorData.");
136
137        let records = vec![
138            BatchResponseRecord::mock("owned-1"),
139            BatchResponseRecord::mock("owned-2"),
140        ];
141        let error_data = BatchErrorData::new(records.clone());
142
143        let mut iter_count = 0;
144        for record in error_data {
145            trace!("Owned iteration item: {:?}", record.custom_id());
146            iter_count += 1;
147        }
148        pretty_assert_eq!(iter_count, records.len(), "Owned iterator should yield all responses.");
149    }
150
151    #[traced_test]
152    fn should_convert_from_vec_of_batch_error_data() {
153        info!("Testing conversion from Vec<BatchErrorData> into BatchErrorData via 'From' impl.");
154
155        let batch_1 = BatchErrorData::new(vec![
156            BatchResponseRecord::mock("from-1"),
157            BatchResponseRecord::mock("from-2"),
158        ]);
159        let batch_2 = BatchErrorData::new(vec![
160            BatchResponseRecord::mock("from-3"),
161        ]);
162
163        let combined = BatchErrorData::from(vec![batch_1, batch_2]);
164        pretty_assert_eq!(combined.len(), 3, "Expected combined data to have length 3.");
165        debug!("Combined length: {}", combined.len());
166
167        let ids = combined.request_ids();
168        pretty_assert_eq!(ids.len(), 3, "Expected 3 request IDs total.");
169        warn!("The request IDs are: {:?}", ids);
170    }
171
172    #[traced_test]
173    fn should_handle_empty_new_batch_error_data() {
174        info!("Testing behavior for an empty BatchErrorData.");
175
176        let error_data = BatchErrorData::new(vec![]);
177        pretty_assert_eq!(error_data.len(), 0, "Should be empty.");
178
179        let iter_count = error_data.iter().count();
180        pretty_assert_eq!(iter_count, 0, "Iteration should yield none for empty data.");
181        let ids = error_data.request_ids();
182        assert!(ids.is_empty(), "No IDs should be returned for empty data.");
183    }
184
185    #[traced_test]
186    fn should_handle_from_empty_vec_of_batch_error_data() {
187        info!("Testing 'From<Vec<BatchErrorData>>' with an empty vector.");
188
189        let batch_error_list: Vec<BatchErrorData> = vec![];
190        let result = BatchErrorData::from(batch_error_list);
191
192        pretty_assert_eq!(result.len(), 0, "Should produce empty BatchErrorData when converting from empty list.");
193        trace!("No data was aggregated, as expected for an empty source.");
194    }
195}