json-spanned-value 0.2.2

Track the origin of your json values for better error reporting!
Documentation
use crate::Settings;

use std::cell::RefCell;
use std::ops::Drop;
use std::sync::{Arc, atomic::{AtomicUsize, AtomicU8, Ordering::Relaxed}};



#[derive(Default)]
pub(crate) struct Shared {
    pub(crate) settings:   Settings,
    pub(crate) start_pos:  AtomicUsize,
    pub(crate) start_ch:   AtomicU8,
    pub(crate) pos:        AtomicUsize,
}

impl Shared {
    pub(crate) fn new(settings: &Settings) -> Self {
        Self {
            settings:   *settings,
            start_pos:  Default::default(),
            start_ch:   Default::default(),
            pos:        Default::default(),
        }
    }
}

thread_local! { static SHARED : RefCell<Option<Arc<Shared>>> = RefCell::new(None); }
pub(crate) fn settings()       -> Option<Settings> { SHARED.with(|s| s.borrow().as_ref().map(|s| s.settings)) }
pub(crate) fn start()          -> Option<(usize, char)> { SHARED.with(|s| s.borrow().as_ref().map(|s| (s.start_pos.load(Relaxed), s.start_ch.load(Relaxed) as char))) }
pub(crate) fn end()            -> Option<usize> { SHARED.with(|s| s.borrow().as_ref().map(|s| s.pos.load(Relaxed))) }



pub(crate) struct SharedStack(Option<Arc<Shared>>);

impl SharedStack {
    pub fn push(shared: Arc<Shared>) -> Self {
        SHARED.with(|s| {
            let mut s = s.borrow_mut();
            Self(std::mem::replace(&mut *s, Some(shared)))
        })
    }
}

impl Drop for SharedStack {
    fn drop(&mut self) {
        SHARED.with(|s| std::mem::swap(&mut *s.borrow_mut(), &mut self.0));
    }
}