cranpose_core/
composer_context.rs1use std::cell::RefCell;
2use std::rc::Rc;
3
4use crate::{Composer, ComposerCore};
5
6thread_local! {
8 static COMPOSER_STACK: RefCell<Vec<Rc<ComposerCore>>> = const { RefCell::new(Vec::new()) };
9}
10
11#[must_use = "ComposerScopeGuard pops the composer stack on drop"]
13pub struct ComposerScopeGuard;
14
15impl Drop for ComposerScopeGuard {
16 fn drop(&mut self) {
17 COMPOSER_STACK.with(|stack| {
18 let mut stack = stack.borrow_mut();
19 stack.pop();
20 });
21 }
22}
23
24pub fn enter(composer: &Composer) -> ComposerScopeGuard {
27 COMPOSER_STACK.with(|stack| {
28 stack.borrow_mut().push(composer.clone_core());
29 });
30 ComposerScopeGuard
31}
32
33pub fn with_composer<R>(f: impl FnOnce(&Composer) -> R) -> R {
38 COMPOSER_STACK.with(|stack| {
39 let core = stack
40 .borrow()
41 .last()
42 .expect("with_composer: no active composer")
43 .clone();
44 let composer = Composer::from_core(core);
45 f(&composer)
46 })
47}
48
49pub fn try_with_composer<R>(f: impl FnOnce(&Composer) -> R) -> Option<R> {
52 COMPOSER_STACK.with(|stack| {
53 let core = stack.borrow().last()?.clone();
54 let composer = Composer::from_core(core);
55 Some(f(&composer))
56 })
57}