forked from Orchid/orchid
I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
39 lines
935 B
Rust
39 lines
935 B
Rust
/// Cache a value in a [thread_local!]. Supports synchronous and asynchronous
|
|
/// initializers
|
|
///
|
|
/// ```
|
|
/// #[macro_use]
|
|
/// use orchid_base::tl_cache;
|
|
///
|
|
/// // simple synchronous case
|
|
/// let foo = tl_cache!(Rc<Vec<usize>>: vec![0; 1024]);
|
|
/// async {
|
|
/// async fn complex_operation(x: usize) -> usize { x + 1 }
|
|
/// // async case
|
|
/// let bar = tl_cache!(async usize: complex_operation(0).await)
|
|
/// }
|
|
/// ```
|
|
#[macro_export]
|
|
macro_rules! tl_cache {
|
|
($ty:ty : $expr:expr) => {{
|
|
thread_local! {
|
|
static V: $ty = $expr;
|
|
}
|
|
V.with(|v| v.clone())
|
|
}};
|
|
(async $ty:ty : $expr:expr) => {{
|
|
type CellType = std::cell::OnceCell<$ty>;
|
|
thread_local! {
|
|
static V: CellType = std::cell::OnceCell::default();
|
|
}
|
|
match V.with(|cell: &CellType| cell.get().cloned()) {
|
|
Some(val) => val as $ty,
|
|
None => {
|
|
let val = $expr;
|
|
let _ = V.with(|cell: &CellType| cell.set(val.clone()));
|
|
val as $ty
|
|
},
|
|
}
|
|
}};
|
|
}
|