• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::convert::From;
2 
3 
4 #[macro_export]
5 macro_rules! try {
6     ($expression: expr) => {
7         match $crate::Triable::try($expression) {
8             $crate::TriableResult::Expression(value) => value,
9             $crate::TriableResult::EarlyReturn(value) => return value,
10         }
11     };
12 }
13 
14 
15 pub enum TriableResult<Expr, Return> {
16     Expression(Expr),
17     EarlyReturn(Return),
18 }
19 
20 
21 pub trait Triable<Expr, Return> {
try(self) -> TriableResult<Expr, Return>22     fn try(self) -> TriableResult<Expr, Return>;
23 }
24 
25 
26 impl<T1, T2, Err1, Err2> Triable<T1, Result<T2, Err2>> for Result<T1, Err1>
27 where Err2: From<Err1> {
try(self) -> TriableResult<T1, Result<T2, Err2>>28     fn try(self) -> TriableResult<T1, Result<T2, Err2>> {
29         match self {
30             Ok(value) => TriableResult::Expression(value),
31             Err(error) => TriableResult::EarlyReturn(Err(From::from(error)))
32         }
33     }
34 }
35 
36 
37 impl<T1, T2> Triable<T1, Option<T2>> for Option<T1> {
try(self) -> TriableResult<T1, Option<T2>>38     fn try(self) -> TriableResult<T1, Option<T2>> {
39         match self {
40             Some(value) => TriableResult::Expression(value),
41             None => TriableResult::EarlyReturn(None)
42         }
43     }
44 }
45 
46 
47 impl<T1, T2> Triable<T1, Result<T2, ()>> for Option<T1> {
try(self) -> TriableResult<T1, Result<T2, ()>>48     fn try(self) -> TriableResult<T1, Result<T2, ()>> {
49         match self {
50             Some(value) => TriableResult::Expression(value),
51             None => TriableResult::EarlyReturn(Err(()))
52         }
53     }
54 }
55 
56 
57 impl<T1, T2> Triable<T1, Option<T2>> for Result<T1, ()> {
try(self) -> TriableResult<T1, Option<T2>>58     fn try(self) -> TriableResult<T1, Option<T2>> {
59         match self {
60             Ok(value) => TriableResult::Expression(value),
61             Err(()) => TriableResult::EarlyReturn(None)
62         }
63     }
64 }
65 
66 
67 impl Triable<(), bool> for bool {
try(self) -> TriableResult<(), bool>68     fn try(self) -> TriableResult<(), bool> {
69         if self {
70             TriableResult::Expression(())
71         } else {
72             TriableResult::EarlyReturn(false)
73         }
74     }
75 }
76 
77 impl<T> Triable<T, bool> for Result<T, ()> {
try(self) -> TriableResult<T, bool>78     fn try(self) -> TriableResult<T, bool> {
79         match self {
80             Ok(value) => TriableResult::Expression(value),
81             Err(()) => TriableResult::EarlyReturn(false)
82         }
83     }
84 }
85 
86 impl<T> Triable<T, bool> for Option<T> {
try(self) -> TriableResult<T, bool>87     fn try(self) -> TriableResult<T, bool> {
88         match self {
89             Some(value) => TriableResult::Expression(value),
90             None => TriableResult::EarlyReturn(false)
91         }
92     }
93 }
94 
95 impl<T> Triable<(), Result<T, ()>> for bool {
try(self) -> TriableResult<(), Result<T, ()>>96     fn try(self) -> TriableResult<(), Result<T, ()>> {
97         if self {
98             TriableResult::Expression(())
99         } else {
100             TriableResult::EarlyReturn(Err(()))
101         }
102     }
103 }
104 
105 
106 impl<T> Triable<(), Option<T>> for bool {
try(self) -> TriableResult<(), Option<T>>107     fn try(self) -> TriableResult<(), Option<T>> {
108         if self {
109             TriableResult::Expression(())
110         } else {
111             TriableResult::EarlyReturn(None)
112         }
113     }
114 }
115 
116 
117 
118 
119 #[test]
result()120 fn result() {
121     fn ok() -> Result<i32, ()> {
122         Ok(try!(Ok(4)))
123     }
124     assert_eq!(ok(), Ok(4));
125 
126     fn err() -> Result<i32, ()> {
127         Ok(try!(Err(())))
128     }
129     assert_eq!(err(), Err(()));
130 }
131 
132 #[test]
option()133 fn option() {
134     fn some() -> Option<i32> {
135         Some(try!(Some(5)))
136     }
137     assert_eq!(some(), Some(5));
138 
139     fn none() -> Option<i32> {
140         Some(try!(None))
141     }
142     assert_eq!(none(), None);
143 }
144 
145 #[test]
option_to_result()146 fn option_to_result() {
147     fn ok() -> Result<i32, ()> {
148         Ok(try!(Some(4)))
149     }
150     assert_eq!(ok(), Ok(4));
151 
152     fn err() -> Result<i32, ()> {
153         Ok(try!(None))
154     }
155     assert_eq!(err(), Err(()));
156 }
157 
158 #[test]
result_to_option()159 fn result_to_option() {
160     fn some() -> Option<i32> {
161         Some(try!(Ok(5)))
162     }
163     assert_eq!(some(), Some(5));
164 
165     fn none() -> Option<i32> {
166         Some(try!(Err(())))
167     }
168     assert_eq!(none(), None);
169 }
170 
171 #[test]
bool()172 fn bool() {
173     fn true_() -> bool {
174         try!(true);
175         true
176     }
177     assert_eq!(true_(), true);
178 
179     fn false_() -> bool {
180         try!(false);
181         true
182     }
183     assert_eq!(false_(), false);
184 }
185 
186 #[test]
option_to_bool()187 fn option_to_bool() {
188     fn true_() -> bool {
189         try!(Some(5));
190         true
191     }
192     assert_eq!(true_(), true);
193 
194     fn false_() -> bool {
195         try!(None);
196         true
197     }
198     assert_eq!(false_(), false);
199 }
200 
201 #[test]
result_to_bool()202 fn result_to_bool() {
203     fn true_() -> bool {
204         try!(Ok(5));
205         true
206     }
207     assert_eq!(true_(), true);
208 
209     fn false_() -> bool {
210         try!(Err(()));
211         true
212     }
213     assert_eq!(false_(), false);
214 }
215 
216 #[test]
bool_to_result()217 fn bool_to_result() {
218     fn ok() -> Result<(), ()> {
219         Ok(try!(true))
220     }
221     assert_eq!(ok(), Ok(()));
222 
223     fn err() -> Result<(), ()> {
224         Ok(try!(false))
225     }
226     assert_eq!(err(), Err(()));
227 }
228 
229 #[test]
bool_to_option()230 fn bool_to_option() {
231     fn some() -> Option<()> {
232         Some(try!(true))
233     }
234     assert_eq!(some(), Some(()));
235 
236     fn none() -> Option<()> {
237         Some(try!(false))
238     }
239     assert_eq!(none(), None);
240 }
241