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
#[macro_export] macro_rules! proc_var { ($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! proc_var_get { ($var:ident) => { $var.with(|var| var.borrow().clone()) }; } #[macro_export] macro_rules! proc_var_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() { proc_var!(LEN, u32, 100); proc_var_set!(LEN, |x| *x = 300); assert_eq!(proc_var_get!(LEN), 300); } #[test] fn test_proc_var_map() { use std::collections::HashMap; proc_var!(MAP, HashMap<String, String>, HashMap::new()); proc_var_set!(MAP, |x| x.insert("a".to_string(), "b".to_string())); assert_eq!(proc_var_get!(MAP)["a"], "b".to_string()); } #[test] fn test_proc_var_vec() { proc_var!(V, Vec<i32>, vec![]); proc_var_set!(V, |v| v.push(100)); proc_var_set!(V, |v| v.push(200)); assert_eq!(proc_var_get!(V)[0], 100); } }