Macro environmental::environmental [−][src]
Declare a new global reference module whose underlying value does not contain references.
Will create a module of a given name that contains two functions:
pub fn using<R, F: FnOnce() -> R>(protected: &mut $t, f: F) -> R
This executesf
, returning its value. During the call, the module’s reference is set to be equal toprotected
.pub fn with<R, F: FnOnce(&mut $t) -> R>(f: F) -> Option<R>
This executesf
, returningSome
of its value if called from code that is being executed as part of ausing
call. If not, it returnsNone
.f
is provided with one argument: the same reference as provided to the most recentusing
call.
Examples
Initializing the global context with a given value.
#[macro_use] extern crate environmental; environmental!(counter: u32); fn main() { let mut counter_value = 41u32; counter::using(&mut counter_value, || { let odd = counter::with(|value| if *value % 2 == 1 { *value += 1; true } else { *value -= 3; false }).unwrap(); // safe because we're inside a counter::using println!("counter was {}", match odd { true => "odd", _ => "even" }); }); println!("The answer is {:?}", counter_value); // 42 }
Roughly the same, but with a trait object:
#[macro_use] extern crate environmental; trait Increment { fn increment(&mut self); } impl Increment for i32 { fn increment(&mut self) { *self += 1 } } environmental!(val: Increment + 'static); fn main() { let mut local = 0i32; val::using(&mut local, || { val::with(|v| for _ in 0..5 { v.increment() }); }); assert_eq!(local, 5); }