1 unstable release
Uses new Rust 2024
new 0.1.0 | May 18, 2025 |
---|
#1458 in Rust patterns
46 downloads per month
9KB
126 lines
Thread-local storage with guarded scopes.
This crate provides thread-local variables whose values can be temporarily overridden within a scope. Each time you call set, a new value is pushed onto the thread-local stack, and a [Guard] is returned. When the guard is dropped, the associated value is removed from the stack. This enables safe, nested overrides of thread-local state.
Usage
Use the [guarded_thread_local] macro to define a thread-local key. Call set to override the value for the current thread and receive a guard. The value is accessible via get while the guard is alive.
use guarded_tls::guarded_thread_local;
guarded_thread_local!(static FOO: String);
let _guard1 = FOO.set("abc".into());
assert_eq!(FOO.get(), "abc");
let guard2 = FOO.set("def".into());
assert_eq!(FOO.get(), "def");
drop(guard2);
assert_eq!(FOO.get(), "abc");
Notes
- get requires the value type to implement [Clone].
- Accessing the value without having a guard will panic.
- Guards dropped out of order have well-defined behavior.
See Also
- scoped-tls: a similar crate for scoped thread-local values.
The main difference between this crate and scoped-tls
is that this crate
doesn't require the nesting of functions, making it some application easier
to manage. For instance creating a test fixture that holds a [Guard].
guarded_tls::guarded_thread_local!(static FOO: u32);
fn create_fixture() -> MyFixture {
MyFixture { foo_guard: FOO.set(123) }
}
fn my_test() {
let fixture = create_fixture();
// Test code here that assumes `FOO` is set.
assert_eq!(FOO.get(), 123);
}
my_test();