abi_stable/std_types/result.rs
1//! Contains the ffi-safe equivalent of `std::result::Result`.
2
3use std::fmt::Debug;
4
5use crate::std_types::{RNone, ROption, RSome};
6
7/// Ffi-safe equivalent of `Result<T, E>`.
8#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
9#[repr(u8)]
10#[derive(StableAbi)]
11pub enum RResult<T, E> {
12 ///
13 #[serde(rename = "Ok")]
14 ROk(T),
15 ///
16 #[serde(rename = "Err")]
17 RErr(E),
18}
19
20pub use self::RResult::*;
21
22#[allow(clippy::missing_const_for_fn)]
23impl<T, E> RResult<T, E> {
24 /// Converts from `RResult<T, E>` to `RResult<&T, &E>`.
25 ///
26 /// # Example
27 ///
28 /// ```
29 /// # use abi_stable::std_types::*;
30 ///
31 /// assert_eq!(ROk::<u32, u32>(10).as_ref(), ROk(&10));
32 /// assert_eq!(RErr::<u32, u32>(5).as_ref(), RErr(&5));
33 ///
34 /// ```
35 #[inline]
36 pub const fn as_ref(&self) -> RResult<&T, &E> {
37 match self {
38 ROk(v) => ROk(v),
39 RErr(v) => RErr(v),
40 }
41 }
42
43 /// Converts from `RResult<T, E>` to `RResult<&mut T, &mut E>`.
44 ///
45 /// # Example
46 ///
47 /// ```
48 /// # use abi_stable::std_types::*;
49 ///
50 /// assert_eq!(ROk::<u32, u32>(10).as_mut(), ROk(&mut 10));
51 /// assert_eq!(RErr::<u32, u32>(5).as_mut(), RErr(&mut 5));
52 ///
53 /// ```
54 #[inline]
55 pub fn as_mut(&mut self) -> RResult<&mut T, &mut E> {
56 match self {
57 ROk(v) => ROk(v),
58 RErr(v) => RErr(v),
59 }
60 }
61
62 /// Returns whether `self` is an `ROk`
63 ///
64 /// # Example
65 ///
66 /// ```
67 /// # use abi_stable::std_types::*;
68 ///
69 /// assert_eq!(ROk::<u32, u32>(10).is_rok(), true);
70 /// assert_eq!(RErr::<u32, u32>(5).is_rok(), false);
71 ///
72 /// ```
73 #[inline]
74 pub const fn is_rok(&self) -> bool {
75 matches! {self, ROk{..}}
76 }
77
78 /// Returns whether `self` is an `ROk`
79 ///
80 /// # Example
81 ///
82 /// ```
83 /// # use abi_stable::std_types::*;
84 ///
85 /// assert_eq!(ROk::<u32, u32>(10).is_ok(), true);
86 /// assert_eq!(RErr::<u32, u32>(5).is_ok(), false);
87 ///
88 /// ```
89 #[inline]
90 pub const fn is_ok(&self) -> bool {
91 matches! {self, ROk{..}}
92 }
93
94 /// Returns whether `self` is an `RErr`
95 ///
96 /// # Example
97 ///
98 /// ```
99 /// # use abi_stable::std_types::*;
100 ///
101 /// assert_eq!(ROk::<u32, u32>(10).is_rerr(), false);
102 /// assert_eq!(RErr::<u32, u32>(5).is_rerr(), true);
103 ///
104 /// ```
105 #[inline]
106 pub const fn is_rerr(&self) -> bool {
107 matches! {self, RErr{..}}
108 }
109
110 /// Returns whether `self` is an `RErr`
111 ///
112 /// # Example
113 ///
114 /// ```
115 /// # use abi_stable::std_types::*;
116 ///
117 /// assert_eq!(ROk::<u32, u32>(10).is_err(), false);
118 /// assert_eq!(RErr::<u32, u32>(5).is_err(), true);
119 ///
120 /// ```
121 #[inline]
122 pub const fn is_err(&self) -> bool {
123 matches! {self, RErr{..}}
124 }
125
126 /// Converts from `RResult<T, E>` to `Result<T, E>`.
127 ///
128 /// # Example
129 ///
130 /// ```
131 /// # use abi_stable::std_types::*;
132 ///
133 /// assert_eq!(ROk::<u32, u32>(10).into_result(), Ok(10));
134 /// assert_eq!(RErr::<u32, u32>(5).into_result(), Err(5));
135 ///
136 /// ```
137 #[inline]
138 pub fn into_result(self) -> Result<T, E> {
139 self.into()
140 }
141
142 /// Converts the `RResult<T, E>` to a `RResult<U, E>` by transforming the value in
143 /// `ROk` using the `op` closure.
144 ///
145 /// # Example
146 ///
147 /// ```
148 /// # use abi_stable::std_types::*;
149 ///
150 /// assert_eq!(ROk::<u32, u32>(10).map(|x| x * 3), ROk(30));
151 /// assert_eq!(RErr::<u32, u32>(5).map(|x| x / 2), RErr(5));
152 ///
153 /// ```
154 #[inline]
155 pub fn map<U, F>(self, op: F) -> RResult<U, E>
156 where
157 F: FnOnce(T) -> U,
158 {
159 match self {
160 ROk(t) => ROk(op(t)),
161 RErr(e) => RErr(e),
162 }
163 }
164
165 /// Converts the `RResult<T, E>` to a `RResult<U, F>` by
166 /// transforming the value in `RErr` using the `op` closure.
167 ///
168 /// # Example
169 ///
170 /// ```
171 /// # use abi_stable::std_types::*;
172 ///
173 /// assert_eq!(ROk::<u32, u32>(10).map_err(|x| x * 3), ROk(10));
174 /// assert_eq!(RErr::<u32, u32>(5).map_err(|x| x / 2), RErr(2));
175 ///
176 /// ```
177 #[inline]
178 pub fn map_err<F, O>(self, op: O) -> RResult<T, F>
179 where
180 O: FnOnce(E) -> F,
181 {
182 match self {
183 ROk(t) => ROk(t),
184 RErr(e) => RErr(op(e)),
185 }
186 }
187
188 /// Converts the `RResult<T, E>` to a `U` by
189 /// transforming the value in `ROk` using the `with_ok` closure,
190 /// otherwise transforming the value in RErr using the `with_err` closure,
191 ///
192 /// # Example
193 ///
194 /// ```
195 /// # use abi_stable::std_types::*;
196 ///
197 /// assert_eq!(ROk::<u32, u32>(10).map_or_else(|_| 77, |x| x * 3), 30);
198 /// assert_eq!(RErr::<u32, u32>(5).map_or_else(|e| e * 4, |x| x / 2), 20);
199 ///
200 /// ```
201 #[inline]
202 pub fn map_or_else<U, M, F>(self, with_err: F, with_ok: M) -> U
203 where
204 M: FnOnce(T) -> U,
205 F: FnOnce(E) -> U,
206 {
207 self.map(with_ok).unwrap_or_else(with_err)
208 }
209
210 /// Returns the result of calling the `op` closure with the value in `ROk`,
211 /// otherwise returning the `RErr` unmodified.
212 ///
213 /// # Example
214 ///
215 /// ```
216 /// # use abi_stable::std_types::*;
217 ///
218 /// assert_eq!(
219 /// ROk::<u32, u32>(10).and_then(|x| ROk::<u32, u32>(x * 3)),
220 /// ROk(30),
221 /// );
222 /// assert_eq!(
223 /// ROk::<u32, u32>(10).and_then(|x| RErr::<u32, u32>(x * 3)),
224 /// RErr(30),
225 /// );
226 /// assert_eq!(
227 /// RErr::<u32, u32>(5).and_then(|x| ROk::<u32, u32>(x / 2)),
228 /// RErr(5),
229 /// );
230 /// assert_eq!(
231 /// RErr::<u32, u32>(5).and_then(|x| RErr::<u32, u32>(x / 2)),
232 /// RErr(5),
233 /// );
234 ///
235 /// ```
236 #[inline]
237 pub fn and_then<U, F>(self, op: F) -> RResult<U, E>
238 where
239 F: FnOnce(T) -> RResult<U, E>,
240 {
241 match self {
242 ROk(t) => op(t),
243 RErr(e) => RErr(e),
244 }
245 }
246
247 /// Returns the result of calling the `op` closure with the value in `RErr`,
248 /// otherwise returning the `ROk` unmodified.
249 ///
250 /// # Example
251 ///
252 /// ```
253 /// # use abi_stable::std_types::*;
254 ///
255 /// assert_eq!(
256 /// ROk::<u32, u32>(10).or_else(|e| ROk::<u32, u32>(e * 3)),
257 /// ROk(10)
258 /// );
259 /// assert_eq!(
260 /// ROk::<u32, u32>(10).or_else(|e| RErr::<u32, u32>(e * 3)),
261 /// ROk(10)
262 /// );
263 /// assert_eq!(
264 /// RErr::<u32, u32>(5).or_else(|e| ROk::<u32, u32>(e / 2)),
265 /// ROk(2)
266 /// );
267 /// assert_eq!(
268 /// RErr::<u32, u32>(5).or_else(|e| RErr::<u32, u32>(e / 2)),
269 /// RErr(2)
270 /// );
271 ///
272 /// ```
273 #[inline]
274 pub fn or_else<F, O>(self, op: O) -> RResult<T, F>
275 where
276 O: FnOnce(E) -> RResult<T, F>,
277 {
278 match self {
279 ROk(t) => ROk(t),
280 RErr(e) => op(e),
281 }
282 }
283
284 /// Unwraps `self`, returning the value in `ROk`.
285 ///
286 /// # Panic
287 ///
288 /// Panics with an error message if `self` is an `RErr`,
289 /// using `E`s Debug implementation.
290 ///
291 /// # Example
292 ///
293 /// ```
294 /// # use abi_stable::std_types::*;
295 ///
296 /// assert_eq!(ROk::<_, ()>(500).unwrap(), 500);
297 ///
298 /// ```
299 ///
300 /// This one panics:
301 /// ```should_panic
302 /// # use abi_stable::std_types::*;
303 ///
304 /// let _ = RErr::<(), _>("Oh noooo!").unwrap();
305 /// ```
306 pub fn unwrap(self) -> T
307 where
308 E: Debug,
309 {
310 self.into_result().unwrap()
311 }
312
313 /// Unwraps `self`, returning the value in `ROk`.
314 ///
315 /// # Panic
316 ///
317 /// Panics with an error message if `self` is an `RErr`,
318 /// using `E`s Debug implementation,
319 /// as well as `message`.
320 ///
321 /// # Example
322 ///
323 /// ```
324 /// # use abi_stable::std_types::*;
325 ///
326 /// assert_eq!(ROk::<_, ()>(500).expect("Are you OK?"), 500);
327 ///
328 /// ```
329 ///
330 /// This one panics:
331 /// ```should_panic
332 /// # use abi_stable::std_types::*;
333 ///
334 /// let _ = RErr::<(), _>(()).expect("This can't be!");
335 /// ```
336 pub fn expect(self, message: &str) -> T
337 where
338 E: Debug,
339 {
340 self.into_result().expect(message)
341 }
342
343 /// Unwraps `self`, returning the value in `RErr`.
344 ///
345 /// # Panic
346 ///
347 /// Panics with an error message if `self` is an `ROk`,
348 /// using `T`s Debug implementation.
349 ///
350 /// # Example
351 ///
352 /// ```
353 /// # use abi_stable::std_types::*;
354 ///
355 /// assert_eq!(RErr::<(), u32>(0xB007).unwrap_err(), 0xB007);
356 ///
357 /// ```
358 ///
359 /// This one panics:
360 /// ```should_panic
361 /// # use abi_stable::std_types::*;
362 ///
363 /// let _ = ROk::<(), ()>(()).unwrap_err();
364 /// ```
365 pub fn unwrap_err(self) -> E
366 where
367 T: Debug,
368 {
369 self.into_result().unwrap_err()
370 }
371
372 /// Unwraps `self`, returning the value in `RErr`.
373 ///
374 /// # Panic
375 ///
376 /// Panics with an error message if `self` is an `ROk`,
377 /// using `T`s Debug implementation,
378 /// as well as `message`.
379 ///
380 /// # Example
381 ///
382 /// ```
383 /// # use abi_stable::std_types::*;
384 ///
385 /// assert_eq!(RErr::<(), u32>(0xB001).expect_err("Murphy's law"), 0xB001);
386 ///
387 /// ```
388 ///
389 /// This one panics:
390 /// ```should_panic
391 /// # use abi_stable::std_types::*;
392 ///
393 /// let _ = ROk::<(), ()>(()).expect_err("Everything is Ok");
394 /// ```
395 pub fn expect_err(self, message: &str) -> E
396 where
397 T: Debug,
398 {
399 self.into_result().expect_err(message)
400 }
401
402 /// Returns the value in `ROk`, or `def` if `self` is `RErr`.
403 ///
404 /// # Example
405 ///
406 /// ```
407 /// # use abi_stable::std_types::*;
408 ///
409 /// assert_eq!(ROk::<u32, u32>(10).unwrap_or(0xEEEE), 10);
410 /// assert_eq!(RErr::<u32, u32>(5).unwrap_or(0b101010), 0b101010);
411 ///
412 /// ```
413 #[inline]
414 pub fn unwrap_or(self, optb: T) -> T {
415 match self {
416 ROk(t) => t,
417 RErr(_) => optb,
418 }
419 }
420
421 /// Returns the value in `ROk`,
422 /// or calls `def` with the error in `RErr`.
423 ///
424 /// # Example
425 ///
426 /// ```
427 /// # use abi_stable::std_types::*;
428 ///
429 /// assert_eq!(ROk::<u32, u32>(10).unwrap_or_else(|e| e * 3), 10);
430 /// assert_eq!(RErr::<u32, u32>(5).unwrap_or_else(|e| e / 2), 2);
431 ///
432 /// ```
433 #[inline]
434 pub fn unwrap_or_else<F>(self, op: F) -> T
435 where
436 F: FnOnce(E) -> T,
437 {
438 match self {
439 ROk(t) => t,
440 RErr(e) => op(e),
441 }
442 }
443
444 /// Returns the value in `ROk`,
445 /// or returns `T::default()` it `self` is an `RErr`.
446 ///
447 /// # Example
448 ///
449 /// ```
450 /// # use abi_stable::std_types::*;
451 ///
452 /// assert_eq!(ROk::<u32, u32>(10).unwrap_or_default(), 10);
453 /// assert_eq!(RErr::<u32, u32>(5).unwrap_or_default(), 0);
454 ///
455 /// ```
456 #[inline]
457 pub fn unwrap_or_default(self) -> T
458 where
459 T: Default,
460 {
461 match self {
462 ROk(t) => t,
463 RErr(_) => Default::default(),
464 }
465 }
466
467 /// Converts from `RResult<T, E>` to `ROption<T>`,
468 /// `ROk` maps to `RSome`, `RErr` maps to `RNone`.
469 ///
470 /// # Example
471 ///
472 /// ```
473 /// # use abi_stable::std_types::*;
474 ///
475 /// assert_eq!(ROk::<u32, u32>(10).ok(), RSome(10));
476 /// assert_eq!(RErr::<u32, u32>(5).ok(), RNone);
477 ///
478 /// ```
479 #[inline]
480 pub fn ok(self) -> ROption<T> {
481 match self {
482 ROk(t) => RSome(t),
483 RErr(_) => RNone,
484 }
485 }
486
487 /// Converts from `RResult<T, E>` to `ROption<T>`,
488 /// `ROk` maps to `RNone`, `RErr` maps to `RSome`.
489 ///
490 /// # Example
491 ///
492 /// ```
493 /// # use abi_stable::std_types::*;
494 ///
495 /// assert_eq!(ROk::<u32, u32>(10).err(), RNone);
496 /// assert_eq!(RErr::<u32, u32>(5).err(), RSome(5));
497 ///
498 /// ```
499 #[inline]
500 pub fn err(self) -> ROption<E> {
501 match self {
502 ROk(_) => RNone,
503 RErr(v) => RSome(v),
504 }
505 }
506}
507
508impl_from_rust_repr! {
509 impl[T, E] From<Result<T, E>> for RResult<T, E> {
510 fn(this){
511 match this {
512 Ok(v) => ROk(v),
513 Err(v) => RErr(v),
514 }
515 }
516 }
517}
518
519impl_into_rust_repr! {
520 impl[T, E] Into<Result<T, E>> for RResult<T, E> {
521 fn(this){
522 match this {
523 ROk(v) => Ok(v),
524 RErr(v) => Err(v),
525 }
526 }
527 }
528}
529
530/////////////////////////////////////////////////////////////////////
531
532//#[cfg(test)]
533#[cfg(all(test, not(feature = "only_new_tests")))]
534mod test {
535 use super::*;
536
537 #[test]
538 fn from_into() {
539 assert_eq!(RResult::from(Ok::<u32, u32>(10)), ROk(10));
540 assert_eq!(RResult::from(Err::<u32, u32>(4)), RErr(4));
541
542 assert_eq!(ROk::<u32, u32>(10).into_result(), Ok(10));
543 assert_eq!(RErr::<u32, u32>(4).into_result(), Err(4));
544 }
545}