1impl<T, E> crate::ResultExt for Result<T, E> {
2 type T = T;
3 type E = E;
4
5 fn expect_with<M, F: FnOnce() -> M>(self, f: F) -> Self::T
6 where
7 Self::E: std::fmt::Debug,
8 M: AsRef<str>,
9 {
10 if let Ok(t) = self {
11 t
12 } else {
13 let msg = f();
14
15 #[allow(clippy::expect_fun_call)]
16 self.expect(msg.as_ref())
17 }
18 }
19
20 fn expect_or_report(self, msg: &str) -> Self::T
21 where
22 Self::E: std::error::Error,
23 {
24 self.map_err(|err| error_reporter::Report::new(err).pretty(true)).expect(msg)
25 }
26
27 fn expect_or_report_with<M, F: FnOnce() -> M>(self, f: F) -> Self::T
28 where
29 Self::E: std::error::Error,
30 M: AsRef<str>,
31 {
32 self.map_err(|err| error_reporter::Report::new(err).pretty(true)).expect_with(f)
33 }
34
35 fn unwrap_or_report(self) -> Self::T
36 where
37 Self::E: std::error::Error,
38 {
39 self.map_err(|err| error_reporter::Report::new(err).pretty(true))
40 .expect("called `unwrap_or_report()` on an `Err` value")
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use crate::ResultExt;
47
48 #[derive(Debug, derive_more::Error, derive_more::Display)]
50 #[display("A mock error occurred")]
51 struct MockError(MockSubError);
52
53 #[derive(Debug, derive_more::Error, derive_more::Display)]
55 #[display("A mock sub error occurred")]
56 struct MockSubError;
57
58 #[test]
60 #[should_panic(expected = "Custom panic: MockError(MockSubError)")]
61 fn expect_err() {
62 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
63 #[allow(clippy::unnecessary_literal_unwrap)]
64 err_val.expect("Custom panic");
65 }
66
67 mod expect_with {
69 use super::*;
70
71 #[test]
72 fn ok() {
73 let ok_val: Result<i32, MockError> = Ok(42);
74 assert_eq!(ok_val.expect_with(|| "Shouldn't see this"), 42);
75 }
76
77 #[test]
78 #[should_panic(expected = "Custom panic: MockError(MockSubError)")]
79 fn err() {
80 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
81 err_val.expect_with(|| "Custom panic");
82 }
83
84 #[test]
85 #[should_panic(expected = "Error in module A: MockError(MockSubError)")]
86 fn err_format() {
87 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
88 let this_module = "module A";
89 err_val.expect_with(|| format!("Error in {}", this_module));
90 }
91
92 #[test]
93 #[should_panic(expected = "Custom panic: MockError(MockSubError)")]
94 fn err_borrowed_string() {
95 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
96 let err_msg = String::from("Custom panic");
97 err_val.expect_with(|| &err_msg);
98 }
99 }
100
101 mod expect_or_report {
103 use super::*;
104
105 #[test]
106 fn ok() {
107 let ok_val: Result<i32, MockError> = Ok(42);
108 assert_eq!(ok_val.expect_or_report("Shouldn't see this"), 42);
109 }
110
111 #[test]
112 #[should_panic(expected = "Custom report: A mock error occurred\n\nCaused by:\n A mock sub error occurred")]
113 fn err() {
114 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
115 err_val.expect_or_report("Custom report");
116 }
117
118 #[test]
119 #[should_panic(expected = "Error in module A: A mock error occurred\n\nCaused by:\n A mock sub error occurred")]
120 fn err_format() {
121 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
122 let this_module = "module A";
123 err_val.expect_or_report(&format!("Error in {}", this_module));
124 }
125 }
126
127 mod expect_or_report_with {
129 use super::*;
130
131 #[test]
132 fn ok() {
133 let ok_val: Result<i32, MockError> = Ok(42);
134 assert_eq!(ok_val.expect_or_report_with(|| "Shouldn't see this"), 42);
135 }
136
137 #[test]
138 #[should_panic(expected = "Dynamic report: A mock error occurred\n\nCaused by:\n A mock sub error occurred")]
139 fn err() {
140 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
141 err_val.expect_or_report_with(|| "Dynamic report");
142 }
143
144 #[test]
145 #[should_panic(expected = "Error in module A: A mock error occurred\n\nCaused by:\n A mock sub error occurred")]
146 fn err_format() {
147 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
148 let this_module = "module A";
149 err_val.expect_or_report_with(|| format!("Error in {}", this_module));
150 }
151 }
152
153 mod unwrap_or_report {
155 use super::*;
156
157 #[test]
158 fn ok() {
159 let ok_val: Result<i32, MockError> = Ok(42);
160 assert_eq!(ok_val.unwrap_or_report(), 42);
161 }
162
163 #[test]
164 #[should_panic(
165 expected = "called `unwrap_or_report()` on an `Err` value: A mock error occurred\n\nCaused by:\n A mock sub error occurred"
166 )]
167 fn err() {
168 let err_val: Result<i32, MockError> = Err(MockError(MockSubError));
169 err_val.unwrap_or_report();
170 }
171 }
172}