veilid_tools/
log_unwrap.rs1use super::*;
4use std::fmt;
5
6pub trait ResultExt<T, E> {
8 fn ok_or_log(self) -> Option<T>
9 where
10 E: fmt::Debug;
11
12 fn unwrap_or_log(self) -> T
13 where
14 E: fmt::Debug;
15
16 fn expect_or_log(self, msg: &str) -> T
17 where
18 E: fmt::Debug;
19
20 fn unwrap_err_or_log(self) -> E
21 where
22 T: fmt::Debug;
23
24 fn expect_err_or_log(self, msg: &str) -> E
25 where
26 T: fmt::Debug;
27}
28
29impl<T, E> ResultExt<T, E> for Result<T, E> {
30 #[inline]
31 #[track_caller]
32 fn ok_or_log(self) -> Option<T>
33 where
34 E: fmt::Debug,
35 {
36 match self {
37 Ok(t) => Some(t),
38 Err(e) => {
39 discarded_with("called `Result::ok_or_log` on an `Err` value", &e);
40 None
41 }
42 }
43 }
44
45 #[inline]
46 #[track_caller]
47 fn unwrap_or_log(self) -> T
48 where
49 E: fmt::Debug,
50 {
51 match self {
52 Ok(t) => t,
53 Err(e) => failed_with("called `Result::unwrap_or_log()` on an `Err` value", &e),
54 }
55 }
56
57 #[inline]
58 #[track_caller]
59 fn expect_or_log(self, msg: &str) -> T
60 where
61 E: fmt::Debug,
62 {
63 match self {
64 Ok(t) => t,
65 Err(e) => failed_with(msg, &e),
66 }
67 }
68
69 #[inline]
70 #[track_caller]
71 fn unwrap_err_or_log(self) -> E
72 where
73 T: fmt::Debug,
74 {
75 match self {
76 Ok(t) => failed_with("called `Result::unwrap_err_or_log()` on an `Ok` value", &t),
77 Err(e) => e,
78 }
79 }
80
81 #[inline]
82 #[track_caller]
83 fn expect_err_or_log(self, msg: &str) -> E
84 where
85 T: fmt::Debug,
86 {
87 match self {
88 Ok(t) => failed_with(msg, &t),
89 Err(e) => e,
90 }
91 }
92}
93
94pub trait OptionExt<T> {
96 fn unwrap_or_log(self) -> T;
97
98 fn expect_or_log(self, msg: &str) -> T;
99
100 fn unwrap_none_or_log(self)
101 where
102 T: fmt::Debug;
103
104 fn expect_none_or_log(self, msg: &str)
105 where
106 T: fmt::Debug;
107}
108
109impl<T> OptionExt<T> for Option<T> {
110 #[inline]
111 #[track_caller]
112 fn unwrap_or_log(self) -> T {
113 match self {
114 Some(val) => val,
115 None => failed("called `Option::unwrap_or_log()` on a `None` value"),
116 }
117 }
118
119 #[inline]
120 #[track_caller]
121 fn expect_or_log(self, msg: &str) -> T {
122 match self {
123 Some(val) => val,
124 None => failed(msg),
125 }
126 }
127
128 #[inline]
129 #[track_caller]
130 fn unwrap_none_or_log(self)
131 where
132 T: fmt::Debug,
133 {
134 if let Some(val) = self {
135 failed_with(
136 "called `Option::unwrap_none_or_log()` on a `Some` value",
137 &val,
138 );
139 }
140 }
141
142 #[inline]
143 #[track_caller]
144 fn expect_none_or_log(self, msg: &str)
145 where
146 T: fmt::Debug,
147 {
148 if let Some(val) = self {
149 failed_with(msg, &val);
150 }
151 }
152}
153
154#[inline(never)]
159#[cold]
160#[track_caller]
161fn failed(msg: &str) -> ! {
162 #[cfg(not(feature = "log-location-quiet"))]
163 {
164 let location = std::panic::Location::caller();
165 #[cfg(feature = "tracing")]
166 error!(
167 unwrap.filepath = location.file(),
168 unwrap.lineno = location.line(),
169 unwrap.columnno = location.column(),
170 "{}",
171 msg
172 );
173 #[cfg(not(feature = "tracing"))]
174 error!(
175 "{}:{}:{} {}",
176 location.file(),
177 location.line(),
178 location.column(),
179 msg
180 );
181 }
182
183 #[cfg(feature = "log-location-quiet")]
184 error!("{}", msg);
185
186 #[cfg(feature = "panic-quiet")]
187 panic!();
188 #[cfg(not(feature = "panic-quiet"))]
189 panic!("{}", msg)
190}
191
192#[inline(never)]
193#[cold]
194#[track_caller]
195fn failed_with(msg: &str, value: &dyn fmt::Debug) -> ! {
196 #[cfg(not(feature = "log-location-quiet"))]
197 {
198 let location = std::panic::Location::caller();
199 #[cfg(feature = "tracing")]
200 error!(
201 unwrap.filepath = location.file(),
202 unwrap.lineno = location.line(),
203 unwrap.columnno = location.column(),
204 "{}: {:?}",
205 msg,
206 &value
207 );
208 #[cfg(not(feature = "tracing"))]
209 error!(
210 "{}:{}:{} {}: {:?}",
211 location.file(),
212 location.line(),
213 location.column(),
214 msg,
215 &value
216 );
217 }
218
219 #[cfg(feature = "log-location-quiet")]
220 error!("{}: {:?}", msg, &value);
221
222 #[cfg(feature = "panic-quiet")]
223 panic!();
224 #[cfg(not(feature = "panic-quiet"))]
225 panic!("{}: {:?}", msg, &value);
226}
227
228#[inline(never)]
229#[cold]
230#[track_caller]
231fn discarded_with(msg: &str, value: &dyn fmt::Debug) {
232 #[cfg(not(feature = "log-location-quiet"))]
233 {
234 let location = std::panic::Location::caller();
235
236 warn!(
237 "{}:{}:{} {}: {:?}",
238 location.file(),
239 location.line(),
240 location.column(),
241 msg,
242 &value
243 );
244 }
245
246 #[cfg(feature = "log-location-quiet")]
247 warn!("{}: {:?}", msg, &value);
248}