cranpose 0.1.145

Cranpose runtime and UI facade
Documentation
use std::{
    cell::RefCell,
    rc::{Rc, Weak},
};

pub(crate) struct ScopedWeakStack<T> {
    stack: RefCell<Vec<Weak<T>>>,
}

impl<T> ScopedWeakStack<T> {
    pub(crate) const fn new() -> Self {
        Self {
            stack: RefCell::new(Vec::new()),
        }
    }

    pub(crate) fn with_scope<R>(&self, value: &Rc<T>, f: impl FnOnce() -> R) -> R {
        struct PopGuard<'a, T>(&'a ScopedWeakStack<T>);

        impl<T> Drop for PopGuard<'_, T> {
            fn drop(&mut self) {
                self.0.stack.borrow_mut().pop();
            }
        }

        self.stack.borrow_mut().push(Rc::downgrade(value));
        let _guard = PopGuard(self);
        f()
    }

    pub(crate) fn current(&self) -> Option<Rc<T>> {
        let mut stack = self.stack.borrow_mut();
        loop {
            match stack.last().and_then(Weak::upgrade) {
                Some(value) => return Some(value),
                None if stack.is_empty() => return None,
                None => {
                    stack.pop();
                }
            }
        }
    }
}