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
use std::any::Any;
use std::boxed::Box;
use std::marker::Send;
use super::super::SpanReference;
pub trait ImplContext : Send {
fn impl_context(&self) -> &Any;
fn clone(&self) -> Box<ImplContext>;
fn reference_span(&mut self, _reference: &SpanReference);
}
pub struct ImplWrapper<T: Any + Clone + Send> {
inner: T
}
impl<T: Any + Clone + Send> ImplWrapper<T> {
pub fn new(inner: T) -> ImplWrapper<T> {
ImplWrapper { inner }
}
}
impl<T: Any + Clone + Send + SpanReferenceAware> ImplContext for ImplWrapper<T> {
fn impl_context(&self) -> &Any {
&self.inner
}
fn clone(&self) -> Box<ImplContext> {
Box::new(ImplWrapper {
inner: self.inner.clone()
})
}
fn reference_span(&mut self, reference: &SpanReference) {
self.inner.reference_span(reference);
}
}
pub trait SpanReferenceAware {
fn reference_span(&mut self, _reference: &SpanReference);
}
#[cfg(test)]
mod tests {
use super::super::super::SpanReference;
use super::ImplContext;
use super::ImplWrapper;
use super::SpanReferenceAware;
#[derive(Debug, Clone)]
struct TestContext {
pub id: String
}
impl SpanReferenceAware for TestContext {
fn reference_span(&mut self, _: &SpanReference) {}
}
#[test]
fn clone_context() {
let clone = {
let context = ImplWrapper::new(TestContext {
id: "ABC".to_owned()
});
context.clone()
};
let inner = clone.impl_context();
if let Some(inner) = inner.downcast_ref::<TestContext>() {
assert_eq!(inner.id, "ABC");
} else {
panic!("Failed to downcast inner context");
}
}
#[test]
fn unwrap_context() {
let context = ImplWrapper::new(TestContext { id: "ABC".to_owned() });
let inner = context.impl_context();
if let Some(inner) = inner.downcast_ref::<TestContext>() {
assert_eq!(inner.id, "ABC");
} else {
panic!("Failed to downcast inner context");
}
}
}