use crate::eval::EvalContext;
use core::cell::RefCell;
use std::collections::HashMap;
use std::path::PathBuf;
use xmltree::XMLNode;
pub(super) struct DepthGuard<'a> {
depth: &'a RefCell<usize>,
}
impl<'a> DepthGuard<'a> {
pub(super) fn new(depth: &'a RefCell<usize>) -> Self {
*depth.borrow_mut() += 1;
Self { depth }
}
}
impl Drop for DepthGuard<'_> {
fn drop(&mut self) {
let mut depth = self.depth.borrow_mut();
*depth = depth.saturating_sub(1);
}
}
pub(super) struct IncludeGuard<'a> {
base_path: &'a RefCell<PathBuf>,
include_stack: &'a RefCell<Vec<PathBuf>>,
namespace_stack: &'a RefCell<Vec<(PathBuf, String)>>,
old_base_path: PathBuf,
include_stack_len: usize,
namespace_stack_len: usize,
}
impl<'a> IncludeGuard<'a> {
pub(super) fn new(
base_path: &'a RefCell<PathBuf>,
include_stack: &'a RefCell<Vec<PathBuf>>,
namespace_stack: &'a RefCell<Vec<(PathBuf, String)>>,
old_base_path: PathBuf,
) -> Self {
let include_stack_len = include_stack.borrow().len();
let namespace_stack_len = namespace_stack.borrow().len();
Self {
base_path,
include_stack,
namespace_stack,
old_base_path,
include_stack_len,
namespace_stack_len,
}
}
}
impl Drop for IncludeGuard<'_> {
fn drop(&mut self) {
*self.base_path.borrow_mut() = self.old_base_path.clone();
let mut include = self.include_stack.borrow_mut();
if include.len() > self.include_stack_len {
include.pop();
}
let mut namespace = self.namespace_stack.borrow_mut();
if namespace.len() > self.namespace_stack_len {
namespace.pop();
}
}
}
pub(super) struct ScopeGuard<'a> {
properties: &'a EvalContext,
}
impl<'a> ScopeGuard<'a> {
pub(super) fn new(properties: &'a EvalContext) -> Self {
Self { properties }
}
}
impl Drop for ScopeGuard<'_> {
fn drop(&mut self) {
self.properties.pop_scope();
}
}
pub(super) struct BlockGuard<'a> {
blocks: &'a RefCell<Vec<HashMap<String, Vec<XMLNode>>>>,
}
impl<'a> BlockGuard<'a> {
pub(super) fn new(blocks: &'a RefCell<Vec<HashMap<String, Vec<XMLNode>>>>) -> Self {
Self { blocks }
}
}
impl Drop for BlockGuard<'_> {
fn drop(&mut self) {
self.blocks.borrow_mut().pop();
}
}
pub(super) struct MacroCallGuard<'a> {
stack: &'a RefCell<Vec<String>>,
}
impl<'a> MacroCallGuard<'a> {
pub(super) fn new(
stack: &'a RefCell<Vec<String>>,
macro_name: String,
) -> Self {
stack.borrow_mut().push(macro_name);
Self { stack }
}
}
impl Drop for MacroCallGuard<'_> {
fn drop(&mut self) {
self.stack.borrow_mut().pop();
}
}