batch_mode_batch_schema/
batch_error_data.rs1crate::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 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 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}