studiole_report/attachments/
attach.rs1use crate::prelude::*;
3
4pub trait Attach: Sized {
6 #[must_use]
8 fn attach(self, name: impl Into<String>, value: impl Display) -> Self;
9
10 #[must_use]
12 fn attach_with<D: Display>(self, name: impl Into<String>, value: impl FnOnce() -> D) -> Self;
13
14 #[must_use]
16 fn attach_path(self, path: impl AsRef<Path>) -> Self;
17}
18
19impl Attach for StructuredError {
20 fn attach(mut self, name: impl Into<String>, value: impl Display) -> Self {
21 self.attached.push(Attachment::new(name, value));
22 self
23 }
24 fn attach_with<D: Display>(
25 mut self,
26 name: impl Into<String>,
27 value: impl FnOnce() -> D,
28 ) -> Self {
29 self.attached.push(Attachment::with(name, value));
30 self
31 }
32 fn attach_path(mut self, path: impl AsRef<Path>) -> Self {
33 self.attached.push(Attachment::path(path));
34 self
35 }
36}
37
38impl<T: StdError + Send + Sync + 'static> Attach for Report<T> {
39 fn attach(mut self, name: impl Into<String>, value: impl Display) -> Self {
40 self.inner.attached.push(Attachment::new(name, value));
41 self
42 }
43 fn attach_with<D: Display>(
44 mut self,
45 name: impl Into<String>,
46 value: impl FnOnce() -> D,
47 ) -> Self {
48 self.inner.attached.push(Attachment::with(name, value));
49 self
50 }
51 fn attach_path(mut self, path: impl AsRef<Path>) -> Self {
52 self.inner.attached.push(Attachment::path(path));
53 self
54 }
55}
56
57impl<T, A: Attach> Attach for Result<T, A> {
58 fn attach(self, name: impl Into<String>, value: impl Display) -> Self {
59 self.map_err(|e| e.attach(name, value))
60 }
61 fn attach_with<D: Display>(self, name: impl Into<String>, value: impl FnOnce() -> D) -> Self {
62 self.map_err(|e| e.attach_with(name, value))
63 }
64 fn attach_path(self, path: impl AsRef<Path>) -> Self {
65 self.map_err(|e| e.attach_path(path))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn structured_error_attach() {
75 let error = StructuredError::new(OuterError::Operation);
77 let error = error.attach("key", "value");
79 assert_eq!(error.attached.len(), 1);
81 }
82
83 #[test]
84 fn report_attach() {
85 let report = Report::new(OuterError::Operation);
87 let error = report.attach("key", "value");
89 assert_eq!(error.attached.len(), 1);
91 }
92
93 #[test]
94 fn result_attach__on_err() {
95 let result: Result<i32, Report<OuterError>> = Err(Report::new(OuterError::Operation));
97 let report = result.attach("key", "value");
99 assert_eq!(report.expect_err("should be err").attached.len(), 1);
101 }
102
103 #[test]
104 fn result_attach__on_ok() {
105 let result: Result<i32, Report<OuterError>> = Ok(42);
107 let result = result.attach("key", "value");
109 assert_eq!(result.expect("should be ok"), 42);
111 }
112
113 #[test]
114 fn result_attach__attach_path() {
115 let result: Result<i32, Report<OuterError>> = Err(Report::new(OuterError::Operation));
117 let result = result.attach_path("/tmp/data.bin");
119 assert_eq!(result.expect_err("should be err").attached.len(), 1);
121 }
122
123 #[test]
124 fn result_attach__attach_with() {
125 let result: Result<i32, Report<OuterError>> = Err(Report::new(OuterError::Operation));
127 let result = result.attach_with("count", || 7);
129 assert_eq!(result.expect_err("should be err").attached.len(), 1);
131 }
132
133 #[test]
134 fn result_attach__structured_error() {
135 let result: Result<i32, StructuredError> = Err(StructuredError::new(OuterError::Operation));
137 let result = result.attach("file", "test.txt");
139 assert_eq!(result.expect_err("should be err").attached.len(), 1);
141 }
142}