1pub fn zip<A, B, E>(
7 result1: Result<A, E>,
8 result2: Result<B, E>,
9) -> Result<(A, B), E> {
10 result1.and_then(|a| result2.map(|b| (a, b)))
11}
12
13pub fn zip_with<A, B, Z, E, F>(
16 result1: Result<A, E>,
17 result2: Result<B, E>,
18 transform: F,
19) -> Result<Z, E>
20where
21 F: FnOnce(A, B) -> Z,
22{
23 zip(result1, result2).map(|(a, b)| transform(a, b))
24}
25
26pub fn zip3<A, B, C, E>(
28 result1: Result<A, E>,
29 result2: Result<B, E>,
30 result3: Result<C, E>,
31) -> Result<(A, B, C), E> {
32 result1.and_then(|a| {
33 result2.and_then(|b| {
34 result3.map(|c| (a, b, c))
35 })
36 })
37}
38
39pub fn zip3_with<A, B, C, Z, E, F>(
41 result1: Result<A, E>,
42 result2: Result<B, E>,
43 result3: Result<C, E>,
44 transform: F,
45) -> Result<Z, E>
46where
47 F: FnOnce(A, B, C) -> Z,
48{
49 zip3(result1, result2, result3).map(|(a, b, c)| transform(a, b, c))
50}
51
52pub fn zip4<A, B, C, D, E>(
54 result1: Result<A, E>,
55 result2: Result<B, E>,
56 result3: Result<C, E>,
57 result4: Result<D, E>,
58) -> Result<(A, B, C, D), E> {
59 result1.and_then(|a| {
60 result2.and_then(|b| {
61 result3.and_then(|c| {
62 result4.map(|d| (a, b, c, d))
63 })
64 })
65 })
66}
67
68pub fn zip4_with<A, B, C, D, Z, E, F>(
70 result1: Result<A, E>,
71 result2: Result<B, E>,
72 result3: Result<C, E>,
73 result4: Result<D, E>,
74 transform: F,
75) -> Result<Z, E>
76where
77 F: FnOnce(A, B, C, D) -> Z,
78{
79 zip4(result1, result2, result3, result4).map(|(a, b, c, d)| transform(a, b, c, d))
80}
81
82pub fn sequence<A, E>(results: Vec<Result<A, E>>) -> Result<Vec<A>, E> {
85 let mut values = Vec::with_capacity(results.len());
86 for result in results {
87 values.push(result?);
88 }
89 Ok(values)
90}
91
92pub fn flat_map<A, B, E, F>(result: Result<A, E>, transform: F) -> Result<B, E>
95where
96 F: FnOnce(A) -> Result<B, E>,
97{
98 result.and_then(transform)
99}
100
101pub fn map<A, B, E, F>(result: Result<A, E>, transform: F) -> Result<B, E>
104where
105 F: FnOnce(A) -> B,
106{
107 result.map(transform)
108}
109
110pub fn map_error<A, E, F, G>(result: Result<A, E>, transform: F) -> Result<A, F>
113where
114 F: FnOnce(E) -> F,
115{
116 result.map_err(transform)
117}
118
119pub fn get_or_else<A, E, F>(result: Result<A, E>, default: F) -> A
122where
123 F: FnOnce() -> A,
124{
125 result.unwrap_or_else(|_| default())
126}
127
128pub fn get_or_default<A, E>(result: Result<A, E>) -> A
130where
131 A: Default,
132{
133 result.unwrap_or_default()
134}
135
136pub fn from_option<A, E>(option: Option<A>, error: E) -> Result<A, E> {
138 option.ok_or(error)
139}
140
141pub fn to_option<A, E>(result: Result<A, E>) -> Option<A> {
143 result.ok()
144}
145
146pub fn or<A, E>(result1: Result<A, E>, result2: Result<A, E>) -> Result<A, E> {
148 match result1 {
149 Ok(value) => Ok(value),
150 Err(_) => result2,
151 }
152}
153
154pub fn or_else<A, E, F>(result: Result<A, E>, fallback: F) -> Result<A, E>
156where
157 F: FnOnce() -> Result<A, E>,
158{
159 match result {
160 Ok(value) => Ok(value),
161 Err(_) => fallback(),
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn test_zip() {
171 let result1: Result<i32, &str> = Ok(5);
172 let result2: Result<String, &str> = Ok("hello".to_string());
173
174 let zipped = zip(result1, result2);
175 assert_eq!(zipped, Ok((5, "hello".to_string())));
176
177 let error_result: Result<i32, &str> = Err("error");
178 let zipped_error = zip(error_result, result2);
179 assert_eq!(zipped_error, Err("error"));
180 }
181
182 #[test]
183 fn test_zip_with() {
184 let result1: Result<i32, &str> = Ok(5);
185 let result2: Result<i32, &str> = Ok(3);
186
187 let zipped = zip_with(result1, result2, |a, b| a + b);
188 assert_eq!(zipped, Ok(8));
189 }
190
191 #[test]
192 fn test_zip3() {
193 let result1: Result<i32, &str> = Ok(1);
194 let result2: Result<i32, &str> = Ok(2);
195 let result3: Result<i32, &str> = Ok(3);
196
197 let zipped = zip3(result1, result2, result3);
198 assert_eq!(zipped, Ok((1, 2, 3)));
199 }
200
201 #[test]
202 fn test_zip3_with() {
203 let result1: Result<i32, &str> = Ok(1);
204 let result2: Result<i32, &str> = Ok(2);
205 let result3: Result<i32, &str> = Ok(3);
206
207 let zipped = zip3_with(result1, result2, result3, |a, b, c| a + b + c);
208 assert_eq!(zipped, Ok(6));
209 }
210
211 #[test]
212 fn test_sequence() {
213 let results = vec![Ok(1), Ok(2), Ok(3)];
214 let sequenced = sequence(results);
215 assert_eq!(sequenced, Ok(vec![1, 2, 3]));
216
217 let error_results = vec![Ok(1), Err("error"), Ok(3)];
218 let sequenced_error = sequence(error_results);
219 assert_eq!(sequenced_error, Err("error"));
220 }
221
222 #[test]
223 fn test_flat_map() {
224 let result: Result<i32, &str> = Ok(5);
225 let mapped = flat_map(result, |x| Ok(x * 2));
226 assert_eq!(mapped, Ok(10));
227
228 let error_result: Result<i32, &str> = Err("error");
229 let mapped_error = flat_map(error_result, |x| Ok(x * 2));
230 assert_eq!(mapped_error, Err("error"));
231 }
232
233 #[test]
234 fn test_map() {
235 let result: Result<i32, &str> = Ok(5);
236 let mapped = map(result, |x| x * 2);
237 assert_eq!(mapped, Ok(10));
238 }
239
240 #[test]
241 fn test_map_error() {
242 let result: Result<i32, &str> = Err("error");
243 let mapped = map_error(result, |e| format!("Error: {}", e));
244 assert_eq!(mapped, Err("Error: error".to_string()));
245 }
246
247 #[test]
248 fn test_get_or_else() {
249 let result: Result<i32, &str> = Ok(5);
250 let value = get_or_else(result, || 0);
251 assert_eq!(value, 5);
252
253 let error_result: Result<i32, &str> = Err("error");
254 let value_error = get_or_else(error_result, || 0);
255 assert_eq!(value_error, 0);
256 }
257
258 #[test]
259 fn test_from_option() {
260 let some_option = Some(5);
261 let result = from_option(some_option, "error");
262 assert_eq!(result, Ok(5));
263
264 let none_option: Option<i32> = None;
265 let result_none = from_option(none_option, "error");
266 assert_eq!(result_none, Err("error"));
267 }
268
269 #[test]
270 fn test_to_option() {
271 let result: Result<i32, &str> = Ok(5);
272 let option = to_option(result);
273 assert_eq!(option, Some(5));
274
275 let error_result: Result<i32, &str> = Err("error");
276 let option_error = to_option(error_result);
277 assert_eq!(option_error, None);
278 }
279
280 #[test]
281 fn test_or() {
282 let result1: Result<i32, &str> = Ok(5);
283 let result2: Result<i32, &str> = Ok(10);
284 let combined = or(result1, result2);
285 assert_eq!(combined, Ok(5));
286
287 let error_result1: Result<i32, &str> = Err("error1");
288 let result2: Result<i32, &str> = Ok(10);
289 let combined_error = or(error_result1, result2);
290 assert_eq!(combined_error, Ok(10));
291 }
292
293 #[test]
294 fn test_or_else() {
295 let result: Result<i32, &str> = Ok(5);
296 let fallback = or_else(result, || Ok(10));
297 assert_eq!(fallback, Ok(5));
298
299 let error_result: Result<i32, &str> = Err("error");
300 let fallback_error = or_else(error_result, || Ok(10));
301 assert_eq!(fallback_error, Ok(10));
302 }
303}