use std::cell::RefCell;
use super::{Path, Segment};
pub struct PathTracker;
impl PathTracker {
pub fn init() {
CURRENT_PATH.with(|path| {
if path.borrow().is_none() {
*path.borrow_mut() = Some(Vec::new());
}
});
}
pub fn push(segment: Segment) {
CURRENT_PATH.with_borrow_mut(|path| path.as_mut().map(|segments| segments.push(segment)));
}
pub fn pop() {
CURRENT_PATH.with_borrow_mut(|path| {
path.as_mut().map(|segments| {
segments.pop();
})
});
}
pub fn current_path() -> Option<Path> {
let segments = CURRENT_PATH.with_borrow(|segments| segments.clone());
segments.map(|segments| segments.into())
}
pub fn stash_current_path_for_error() {
PATH_ON_ERROR.with_borrow_mut(|stashed| {
let current = Self::current_path();
let Some(stashed) = stashed else {
*stashed = current;
return;
};
let Some(current) = current else {
return;
};
if !stashed.segments().starts_with(current.segments()) {
*stashed = current;
}
});
}
pub fn unstash_current_path_for_error() -> Option<Path> {
PATH_ON_ERROR.take()
}
pub fn try_unset() {
let _ = CURRENT_PATH.try_with(|s| {
if let Ok(mut s) = s.try_borrow_mut() {
*s = None;
}
});
}
}
thread_local! {
static CURRENT_PATH: RefCell<Option<Vec<Segment>>> = const { RefCell::new(None) };
static PATH_ON_ERROR: RefCell<Option<Path>> = const { RefCell::new(None) };
}