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
#[macro_export]
macro_rules! tls_init {
($vis:vis $var:ident, $t:ty, $($var_init:tt)*) => {
thread_local!{
$vis static $var: std::cell::RefCell<$t> =
std::cell::RefCell::new($($var_init)*);
}
};
}
#[macro_export]
macro_rules! tls_get {
($var:ident) => {
$var.with(|var| var.borrow().clone())
};
}
#[macro_export]
macro_rules! tls_set {
($var:ident, |$v:ident| $($var_update:tt)*) => {
$var.with(|$v| {
let mut $v = $v.borrow_mut();
$($var_update)*;
});
};
}
#[cfg(test)]
mod tests {
#[test]
fn test_proc_var_u32() {
tls_init!(LEN, u32, 100);
tls_set!(LEN, |x| *x = 300);
assert_eq!(tls_get!(LEN), 300);
}
#[test]
fn test_proc_var_map() {
use std::collections::HashMap;
tls_init!(MAP, HashMap<String, String>, HashMap::new());
tls_set!(MAP, |x| x.insert("a".to_string(), "b".to_string()));
assert_eq!(tls_get!(MAP)["a"], "b".to_string());
}
#[test]
fn test_proc_var_vec() {
tls_init!(V, Vec<i32>, vec![]);
tls_set!(V, |v| v.push(100));
tls_set!(V, |v| v.push(200));
assert_eq!(tls_get!(V)[0], 100);
}
}