1use core::error::Error;
2
3use crate::{Attachment, IntoReport, OpaqueAttachment, Report};
4
5pub trait ResultExt {
8 type Context: ?Sized;
10
11 type Ok;
13
14 fn attach<A>(self, attachment: A) -> Result<Self::Ok, Report<Self::Context>>
19 where
20 A: Attachment;
21
22 fn attach_with<A, F>(self, attachment: F) -> Result<Self::Ok, Report<Self::Context>>
27 where
28 A: Attachment,
29 F: FnOnce() -> A;
30
31 fn attach_opaque<A>(self, attachment: A) -> Result<Self::Ok, Report<Self::Context>>
35 where
36 A: OpaqueAttachment;
37
38 fn attach_opaque_with<A, F>(self, attachment: F) -> Result<Self::Ok, Report<Self::Context>>
42 where
43 A: OpaqueAttachment,
44 F: FnOnce() -> A;
45
46 fn change_context<C>(self, context: C) -> Result<Self::Ok, Report<C>>
50 where
51 C: Error + Send + Sync + 'static;
52
53 fn change_context_lazy<C, F>(self, context: F) -> Result<Self::Ok, Report<C>>
57 where
58 C: Error + Send + Sync + 'static,
59 F: FnOnce() -> C;
60}
61
62impl<T, E> ResultExt for Result<T, E>
63where
64 E: IntoReport,
65{
66 type Context = E::Context;
67 type Ok = T;
68
69 #[track_caller]
70 fn attach<A>(self, attachment: A) -> Result<T, Report<E::Context>>
71 where
72 A: Attachment,
73 {
74 match self {
75 Ok(value) => Ok(value),
76 Err(error) => Err(error.into_report().attach(attachment)),
77 }
78 }
79
80 #[track_caller]
81 fn attach_with<A, F>(self, attachment: F) -> Result<T, Report<E::Context>>
82 where
83 A: Attachment,
84 F: FnOnce() -> A,
85 {
86 match self {
87 Ok(value) => Ok(value),
88 Err(error) => Err(error.into_report().attach(attachment())),
89 }
90 }
91
92 #[track_caller]
93 fn attach_opaque<A>(self, attachment: A) -> Result<T, Report<E::Context>>
94 where
95 A: OpaqueAttachment,
96 {
97 match self {
98 Ok(value) => Ok(value),
99 Err(error) => Err(error.into_report().attach_opaque(attachment)),
100 }
101 }
102
103 #[track_caller]
104 fn attach_opaque_with<A, F>(self, attachment: F) -> Result<T, Report<E::Context>>
105 where
106 A: OpaqueAttachment,
107 F: FnOnce() -> A,
108 {
109 match self {
110 Ok(value) => Ok(value),
111 Err(error) => Err(error.into_report().attach_opaque(attachment())),
112 }
113 }
114
115 #[track_caller]
116 fn change_context<C>(self, context: C) -> Result<T, Report<C>>
117 where
118 C: Error + Send + Sync + 'static,
119 {
120 match self {
121 Ok(value) => Ok(value),
122 Err(error) => Err(error.into_report().change_context(context)),
123 }
124 }
125
126 #[track_caller]
127 fn change_context_lazy<C, F>(self, context: F) -> Result<T, Report<C>>
128 where
129 C: Error + Send + Sync + 'static,
130 F: FnOnce() -> C,
131 {
132 match self {
133 Ok(value) => Ok(value),
134 Err(error) => Err(error.into_report().change_context(context())),
135 }
136 }
137}