1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#![deny(missing_docs)]
#![doc(html_root_url = "http://arcnmx.github.io/result-rs/")]
pub mod prelude {
pub use super::{ResultOptionExt, ResultIteratorExt};
}
pub use ::ResultOptionExt as OptionResultExt;
pub trait ResultOptionExt {
type Out;
fn invert(self) -> Self::Out;
}
impl<T, E> OptionResultExt for Option<Result<T, E>> {
type Out = Result<Option<T>, E>;
fn invert(self) -> Self::Out {
match self {
Some(Err(e)) => Err(e),
Some(Ok(v)) => Ok(Some(v)),
None => Ok(None)
}
}
}
impl<T, E> ResultOptionExt for Result<Option<T>, E> {
type Out = Option<Result<T, E>>;
fn invert(self) -> Self::Out {
match self {
Ok(None) => None,
Ok(Some(v)) => Some(Ok(v)),
Err(e) => Some(Err(e)),
}
}
}
pub trait ResultIteratorExt {
type Val;
type Err;
fn next_invert(&mut self) -> Result<Option<Self::Val>, Self::Err>;
}
impl<T, E, I: Iterator<Item=Result<T, E>>> ResultIteratorExt for I {
type Val = T;
type Err = E;
fn next_invert(&mut self) -> Result<Option<Self::Val>, Self::Err> {
self.next().invert()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_option_result() {
use std::iter;
let mut iter = iter::once(Err::<(), _>(0));
let err = iter.next();
assert!(err.invert().is_err());
assert_eq!(err.invert().invert(), err);
let none = iter.next();
assert_eq!(none.invert(), Ok(None));
assert_eq!(none.invert().invert(), none);
}
}