error2/
option_ext.rs

1use std::{error::Error, fmt};
2
3use crate::{Error2, ErrorWrap, Location};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct NoneError;
7
8impl fmt::Display for NoneError {
9    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10        write!(f, "NoneError")
11    }
12}
13
14impl Error for NoneError {}
15
16pub trait OptionExt<T>: Sized {
17    #[track_caller]
18    fn context<C, E>(self, context: C) -> Result<T, E>
19    where
20        C: ErrorWrap<NoneError, E>,
21        E: Error2,
22    {
23        self.context_and_location(context, Location::caller())
24    }
25
26    fn context_and_location<C, E>(self, context: C, location: Location) -> Result<T, E>
27    where
28        C: ErrorWrap<NoneError, E>,
29        E: Error2;
30
31    #[track_caller]
32    fn with_context<F, C, E>(self, f: F) -> Result<T, E>
33    where
34        F: FnOnce() -> C,
35        C: ErrorWrap<NoneError, E>,
36        E: Error2,
37    {
38        self.with_context_and_location(f, Location::caller())
39    }
40
41    fn with_context_and_location<F, C, E>(self, f: F, location: Location) -> Result<T, E>
42    where
43        F: FnOnce() -> C,
44        C: ErrorWrap<NoneError, E>,
45        E: Error2;
46}
47
48impl<T> OptionExt<T> for Option<T> {
49    fn context_and_location<C, E>(self, context: C, location: Location) -> Result<T, E>
50    where
51        C: ErrorWrap<NoneError, E>,
52        E: Error2,
53    {
54        match self {
55            Some(t) => Ok(t),
56            None => Err(context.wrap(NoneError, location)),
57        }
58    }
59
60    fn with_context_and_location<F, C, E>(self, f: F, location: Location) -> Result<T, E>
61    where
62        F: FnOnce() -> C,
63        C: ErrorWrap<NoneError, E>,
64        E: Error2,
65    {
66        match self {
67            Some(t) => Ok(t),
68            None => {
69                let context = f();
70                Err(context.wrap(NoneError, location))
71            }
72        }
73    }
74}