1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::{
collections::hash_map::{Entry, HashMap},
error::Error,
fmt,
};
use error_stack::{bail, AttachmentKind, FrameKind, Report, Result, ResultExt};
use serde::Serialize;
#[derive(Debug)]
enum MapError {
Occupied { key: &'static str, value: u64 },
}
impl fmt::Display for MapError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Occupied { key, value } => {
write!(fmt, "Entry \"{key}\" is already occupied by {value}")
}
}
}
}
impl Error for MapError {}
fn create_new_entry(
map: &mut HashMap<&str, u64>,
key: &'static str,
value: u64,
) -> Result<(), MapError> {
match map.entry(key) {
Entry::Occupied(entry) => {
bail!(MapError::Occupied {
key,
value: *entry.get()
})
}
Entry::Vacant(entry) => {
entry.insert(value);
}
}
Ok(())
}
fn main() -> Result<(), MapError> {
Report::set_debug_hook(|report, fmt| {
#[derive(Serialize)]
struct Context {
context: String,
attachments: Vec<String>,
}
let mut output = Vec::new();
let mut attachments = Vec::new();
for frame in report.frames() {
match frame.kind() {
FrameKind::Context(context) => {
output.push(Context {
context: context.to_string(),
attachments: attachments.clone(),
});
attachments.clear();
}
FrameKind::Attachment(AttachmentKind::Printable(attachment)) => {
attachments.push(attachment.to_string());
}
FrameKind::Attachment(_) => {}
}
}
if fmt.alternate() {
fmt.write_str(&serde_json::to_string_pretty(&output).expect("Could not format report"))
} else {
fmt.write_str(&serde_json::to_string(&output).expect("Could not format report"))
}
})
.expect("Hook was set twice");
let mut config = HashMap::default();
create_new_entry(&mut config, "foo", 1).attach_printable("Could not create new entry")?;
create_new_entry(&mut config, "foo", 2).attach_printable("Could not create new entry")?;
Ok(())
}