1use ::alloc::borrow::Cow;
4
5use crate::{
6 NeuErr,
7 features::{AnyDebugSendSync, ErrorSendSync},
8};
9
10pub trait CtxResultExt: Sized {
12 #[track_caller]
14 #[must_use]
15 fn context<C>(self, context: C) -> Self
16 where
17 C: Into<Cow<'static, str>>;
18
19 #[track_caller]
21 #[must_use]
22 fn context_with<F, C>(self, context_fn: F) -> Self
23 where
24 F: FnOnce() -> C,
25 C: Into<Cow<'static, str>>;
26
27 #[must_use]
32 fn attach<C>(self, context: C) -> Self
33 where
34 C: AnyDebugSendSync + 'static;
35
36 #[must_use]
41 fn attach_with<F, C>(self, context_fn: F) -> Self
42 where
43 F: FnOnce() -> C,
44 C: AnyDebugSendSync + 'static;
45
46 #[must_use]
51 fn attach_override<C>(self, context: C) -> Self
52 where
53 C: AnyDebugSendSync + 'static;
54
55 #[must_use]
60 fn attach_override_with<F, C>(self, context_fn: F) -> Self
61 where
62 F: FnOnce() -> C,
63 C: AnyDebugSendSync + 'static;
64}
65
66impl<T> CtxResultExt for Result<T, NeuErr> {
67 #[track_caller]
68 #[inline]
69 fn context<C>(self, context: C) -> Self
70 where
71 C: Into<Cow<'static, str>>,
72 {
73 match self {
75 Ok(value) => Ok(value),
76 Err(err) => Err(err.context(context)),
77 }
78 }
79
80 #[track_caller]
81 #[inline]
82 fn context_with<F, C>(self, context_fn: F) -> Self
83 where
84 F: FnOnce() -> C,
85 C: Into<Cow<'static, str>>,
86 {
87 match self {
89 Ok(value) => Ok(value),
90 Err(err) => Err(err.context(context_fn())),
91 }
92 }
93
94 #[inline]
95 fn attach<C>(self, context: C) -> Self
96 where
97 C: AnyDebugSendSync + 'static,
98 {
99 self.map_err(|err| err.attach(context))
100 }
101
102 #[inline]
103 fn attach_with<F, C>(self, context_fn: F) -> Self
104 where
105 F: FnOnce() -> C,
106 C: AnyDebugSendSync + 'static,
107 {
108 self.map_err(|err| err.attach(context_fn()))
109 }
110
111 #[inline]
112 fn attach_override<C>(self, context: C) -> Self
113 where
114 C: AnyDebugSendSync + 'static,
115 {
116 self.map_err(|err| err.attach_override(context))
117 }
118
119 #[inline]
120 fn attach_override_with<F, C>(self, context_fn: F) -> Self
121 where
122 F: FnOnce() -> C,
123 C: AnyDebugSendSync + 'static,
124 {
125 self.map_err(|err| err.attach_override(context_fn()))
126 }
127}
128
129
130pub trait ConvertResult<T, E>: Sized {
132 #[track_caller]
134 fn context<C>(self, context: C) -> Result<T, NeuErr>
135 where
136 C: Into<Cow<'static, str>>;
137
138 #[track_caller]
140 fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
141 where
142 F: FnOnce(&E) -> C,
143 C: Into<Cow<'static, str>>;
144
145 fn attach<C>(self, context: C) -> Result<T, NeuErr>
150 where
151 C: AnyDebugSendSync + 'static;
152
153 fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
158 where
159 F: FnOnce(&E) -> C,
160 C: AnyDebugSendSync + 'static;
161
162 fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
167 where
168 C: AnyDebugSendSync + 'static;
169
170 fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
175 where
176 F: FnOnce(&E) -> C,
177 C: AnyDebugSendSync + 'static;
178}
179
180impl<T, E> ConvertResult<T, E> for Result<T, E>
181where
182 E: ErrorSendSync + 'static,
183{
184 #[track_caller]
185 #[inline]
186 fn context<C>(self, context: C) -> Result<T, NeuErr>
187 where
188 C: Into<Cow<'static, str>>,
189 {
190 match self {
192 Ok(value) => Ok(value),
193 Err(err) => Err(NeuErr::from_source(err).context(context)),
194 }
195 }
196
197 #[track_caller]
198 #[inline]
199 fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
200 where
201 F: FnOnce(&E) -> C,
202 C: Into<Cow<'static, str>>,
203 {
204 match self {
206 Ok(value) => Ok(value),
207 Err(err) => {
208 let context = context_fn(&err);
209 Err(NeuErr::from_source(err).context(context))
210 }
211 }
212 }
213
214 #[inline]
215 fn attach<C>(self, context: C) -> Result<T, NeuErr>
216 where
217 C: AnyDebugSendSync + 'static,
218 {
219 self.map_err(|err| NeuErr::from_source(err).attach(context))
220 }
221
222 #[inline]
223 fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
224 where
225 F: FnOnce(&E) -> C,
226 C: AnyDebugSendSync + 'static,
227 {
228 self.map_err(|err| {
229 let attach = context_fn(&err);
230 NeuErr::from_source(err).attach(attach)
231 })
232 }
233
234 #[inline]
235 fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
236 where
237 C: AnyDebugSendSync + 'static,
238 {
239 self.map_err(|err| NeuErr::from_source(err).attach_override(context))
240 }
241
242 #[inline]
243 fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
244 where
245 F: FnOnce(&E) -> C,
246 C: AnyDebugSendSync + 'static,
247 {
248 self.map_err(|err| {
249 let attach = context_fn(&err);
250 NeuErr::from_source(err).attach_override(attach)
251 })
252 }
253}
254
255
256pub trait ConvertOption<T>: Sized {
258 #[track_caller]
260 fn context<C>(self, context: C) -> Result<T, NeuErr>
261 where
262 C: Into<Cow<'static, str>>;
263
264 #[track_caller]
266 fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
267 where
268 F: FnOnce() -> C,
269 C: Into<Cow<'static, str>>;
270
271 fn attach<C>(self, context: C) -> Result<T, NeuErr>
276 where
277 C: AnyDebugSendSync + 'static;
278
279 fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
284 where
285 F: FnOnce() -> C,
286 C: AnyDebugSendSync + 'static;
287
288 fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
293 where
294 C: AnyDebugSendSync + 'static;
295
296 fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
301 where
302 F: FnOnce() -> C,
303 C: AnyDebugSendSync + 'static;
304}
305
306impl<T> ConvertOption<T> for Option<T> {
307 #[track_caller]
308 #[inline]
309 fn context<C>(self, context: C) -> Result<T, NeuErr>
310 where
311 C: Into<Cow<'static, str>>,
312 {
313 match self {
315 Some(value) => Ok(value),
316 None => Err(NeuErr::new(context)),
317 }
318 }
319
320 #[track_caller]
321 #[inline]
322 fn context_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
323 where
324 F: FnOnce() -> C,
325 C: Into<Cow<'static, str>>,
326 {
327 match self {
329 Some(value) => Ok(value),
330 None => {
331 let context = context_fn();
332 Err(NeuErr::new(context))
333 }
334 }
335 }
336
337 #[inline]
338 fn attach<C>(self, context: C) -> Result<T, NeuErr>
339 where
340 C: AnyDebugSendSync + 'static,
341 {
342 self.ok_or_else(|| NeuErr::default().attach(context))
343 }
344
345 #[inline]
346 fn attach_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
347 where
348 F: FnOnce() -> C,
349 C: AnyDebugSendSync + 'static,
350 {
351 self.ok_or_else(|| {
352 let attach = context_fn();
353 NeuErr::default().attach(attach)
354 })
355 }
356
357 #[inline]
358 fn attach_override<C>(self, context: C) -> Result<T, NeuErr>
359 where
360 C: AnyDebugSendSync + 'static,
361 {
362 self.ok_or_else(|| NeuErr::default().attach_override(context))
363 }
364
365 #[inline]
366 fn attach_override_with<F, C>(self, context_fn: F) -> Result<T, NeuErr>
367 where
368 F: FnOnce() -> C,
369 C: AnyDebugSendSync + 'static,
370 {
371 self.ok_or_else(|| {
372 let attach = context_fn();
373 NeuErr::default().attach_override(attach)
374 })
375 }
376}
377
378
379pub trait ResultExt<T, E> {
381 fn or_collect<C>(self, collection: &mut C) -> Option<T>
383 where
384 C: Extend<E>;
385}
386
387impl<T, E> ResultExt<T, E> for Result<T, E> {
388 #[inline]
389 fn or_collect<C>(self, collection: &mut C) -> Option<T>
390 where
391 C: Extend<E>,
392 {
393 match self {
394 Ok(value) => Some(value),
395 Err(err) => {
396 collection.extend(core::iter::once(err));
397 None
398 }
399 }
400 }
401}