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
107
108
109
110
111
112
113
114
115
116
117
118
#[cfg(doc)]
use crate::Event;
use crate::{Object, RToC, Value};
use std::{
collections::BTreeMap,
ffi::CStr,
ops::{Deref, DerefMut},
ptr,
};
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct Breadcrumb {
pub ty: Option<String>,
pub message: Option<String>,
pub map: BTreeMap<String, Value>,
}
impl Default for Breadcrumb {
fn default() -> Self {
Self::new(None, None)
}
}
impl Object for Breadcrumb {
fn into_parts(self) -> (sys::Value, BTreeMap<String, Value>) {
let ty = self.ty.map(RToC::into_cstring);
let ty = ty.as_deref().map_or(ptr::null(), CStr::as_ptr);
let message = self.message.map(RToC::into_cstring);
let message = message.as_deref().map_or(ptr::null(), CStr::as_ptr);
(unsafe { sys::value_new_breadcrumb(ty, message) }, self.map)
}
}
impl Deref for Breadcrumb {
type Target = BTreeMap<String, Value>;
fn deref(&self) -> &Self::Target {
&self.map
}
}
impl DerefMut for Breadcrumb {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.map
}
}
impl Breadcrumb {
#[must_use = "`Breadcrumb` doesn't do anything without `Breadcrumb::add`"]
#[allow(clippy::missing_const_for_fn)]
pub fn new(r#type: Option<String>, message: Option<String>) -> Self {
Self {
ty: r#type,
message,
map: BTreeMap::new(),
}
}
pub fn insert<S: Into<String>, V: Into<Value>>(&mut self, key: S, value: V) {
self.deref_mut().insert(key.into(), value.into());
}
pub fn add(self) {
let breadcrumb = self.into_raw();
unsafe { sys::add_breadcrumb(breadcrumb) }
}
}
#[test]
fn breadcrumb() {
let breadcrumb = Breadcrumb::new(Some("test".into()), Some("test".into()));
assert_eq!(Some("test".into()), breadcrumb.ty);
assert_eq!(Some("test".into()), breadcrumb.message);
breadcrumb.add();
let mut breadcrumb = Breadcrumb::new(None, None);
breadcrumb.insert("test", "test");
assert_eq!(Some("test"), breadcrumb.get("test").and_then(Value::as_str));
breadcrumb.add();
}