1use crate::exn::Exn;
16
17pub trait ErrorExt: std::error::Error + Send + Sync + 'static {
19 #[track_caller]
21 fn raise(self) -> Exn<Self>
22 where
23 Self: Sized,
24 {
25 Exn::new(self)
26 }
27
28 #[track_caller]
41 fn and_raise<T: std::error::Error + Send + Sync + 'static>(self, context: T) -> Exn<T>
42 where
43 Self: Sized,
44 {
45 Exn::new(self).raise(context)
46 }
47
48 #[track_caller]
50 fn raise_erased(self) -> Exn
51 where
52 Self: Sized,
53 {
54 Exn::new(self).erased()
55 }
56
57 #[track_caller]
59 fn raise_all<T, I>(self, sources: I) -> Exn<Self>
60 where
61 Self: Sized,
62 T: std::error::Error + Send + Sync + 'static,
63 I: IntoIterator,
64 I::Item: Into<Exn<T>>,
65 {
66 Exn::raise_all(sources, self)
67 }
68}
69
70impl<T> ErrorExt for T where T: std::error::Error + Send + Sync + 'static {}
71
72pub trait OptionExt {
74 type Some;
76
77 fn ok_or_raise<A, F>(self, err: F) -> Result<Self::Some, Exn<A>>
79 where
80 A: std::error::Error + Send + Sync + 'static,
81 F: FnOnce() -> A;
82
83 fn ok_or_raise_erased<A, F>(self, err: F) -> Result<Self::Some, Exn>
85 where
86 A: std::error::Error + Send + Sync + 'static,
87 F: FnOnce() -> A;
88}
89
90impl<T> OptionExt for Option<T> {
91 type Some = T;
92
93 #[track_caller]
94 fn ok_or_raise<A, F>(self, err: F) -> Result<T, Exn<A>>
95 where
96 A: std::error::Error + Send + Sync + 'static,
97 F: FnOnce() -> A,
98 {
99 match self {
100 Some(v) => Ok(v),
101 None => Err(Exn::new(err())),
102 }
103 }
104
105 #[track_caller]
106 fn ok_or_raise_erased<A, F>(self, err: F) -> Result<T, Exn>
107 where
108 A: std::error::Error + Send + Sync + 'static,
109 F: FnOnce() -> A,
110 {
111 self.ok_or_raise(err).map_err(Exn::erased)
112 }
113}
114
115pub trait ResultExt {
117 type Success;
119
120 type Error: std::error::Error + Send + Sync + 'static;
122
123 fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
127 where
128 A: std::error::Error + Send + Sync + 'static,
129 F: FnOnce() -> A;
130
131 fn or_erased(self) -> Result<Self::Success, Exn>;
135
136 fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
140 where
141 A: std::error::Error + Send + Sync + 'static,
142 F: FnOnce() -> A;
143}
144
145impl<T, E> ResultExt for Result<T, E>
146where
147 E: std::error::Error + Send + Sync + 'static,
148{
149 type Success = T;
150 type Error = E;
151
152 #[track_caller]
153 fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
154 where
155 A: std::error::Error + Send + Sync + 'static,
156 F: FnOnce() -> A,
157 {
158 match self {
159 Ok(v) => Ok(v),
160 Err(e) => Err(Exn::new(e).raise(err())),
161 }
162 }
163
164 #[track_caller]
165 fn or_erased(self) -> Result<Self::Success, Exn> {
166 match self {
167 Ok(v) => Ok(v),
168 Err(e) => Err(Exn::new(e).erased()),
169 }
170 }
171
172 #[track_caller]
173 fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
174 where
175 A: std::error::Error + Send + Sync + 'static,
176 F: FnOnce() -> A,
177 {
178 self.or_raise(err).map_err(Exn::erased)
179 }
180}
181
182impl<T, E> ResultExt for Result<T, Exn<E>>
183where
184 E: std::error::Error + Send + Sync + 'static,
185{
186 type Success = T;
187 type Error = E;
188
189 #[track_caller]
190 fn or_raise<A, F>(self, err: F) -> Result<Self::Success, Exn<A>>
191 where
192 A: std::error::Error + Send + Sync + 'static,
193 F: FnOnce() -> A,
194 {
195 match self {
196 Ok(v) => Ok(v),
197 Err(e) => Err(e.raise(err())),
198 }
199 }
200
201 #[track_caller]
202 fn or_erased(self) -> Result<Self::Success, Exn> {
203 match self {
204 Ok(v) => Ok(v),
205 Err(e) => Err(e.erased()),
206 }
207 }
208
209 #[track_caller]
210 fn or_raise_erased<A, F>(self, err: F) -> Result<Self::Success, Exn>
211 where
212 A: std::error::Error + Send + Sync + 'static,
213 F: FnOnce() -> A,
214 {
215 self.or_raise(err).map_err(Exn::erased)
216 }
217}