Skip to main content

runmat_runtime/
source_context.rs

1use runmat_thread_local::runmat_thread_local;
2use std::cell::RefCell;
3use std::sync::Arc;
4
5runmat_thread_local! {
6    static CURRENT_SOURCE: RefCell<Option<Arc<str>>> = const { RefCell::new(None) };
7}
8
9pub struct SourceContextGuard {
10    prev: Option<Arc<str>>,
11}
12
13impl Drop for SourceContextGuard {
14    fn drop(&mut self) {
15        let prev = self.prev.take();
16        CURRENT_SOURCE.with(|slot| {
17            *slot.borrow_mut() = prev;
18        });
19    }
20}
21
22/// Replace the current source text for this thread.
23///
24/// This is used for UX features like "show the original expression" in legends and for
25/// diagnostics that need to slice the source by byte-span.
26pub fn replace_current_source(source: Option<&str>) -> SourceContextGuard {
27    let next = source.map(Arc::<str>::from);
28    let prev = CURRENT_SOURCE.with(|slot| std::mem::replace(&mut *slot.borrow_mut(), next));
29    SourceContextGuard { prev }
30}
31
32pub fn current_source() -> Option<Arc<str>> {
33    CURRENT_SOURCE.with(|slot| slot.borrow().clone())
34}