use core::{clone, cmp, fmt, marker};
use crate::{RefIter, RefStack};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VarStackEntry<S, V> {
pub name: S,
pub value: V,
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VarStack<'s, S, V>(pub RefStack<'s, VarStackEntry<S, V>>);
impl<S: Copy + fmt::Debug, V: fmt::Debug> fmt::Debug for VarStack<'_, S, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish()
}
}
impl<'s, S, V> VarStack<'s, S, V> {
pub fn find(&self, name: &S) -> Option<&V>
where
S: cmp::PartialEq,
{
let mut this = &self.0;
while &this.value.name != name {
this = *this.parent.as_ref()?;
}
Some(&this.value.value)
}
#[inline(always)]
pub fn iter(&'s self) -> VarIter<'s, S, V>
where
S: Copy,
{
VarIter(self.0.iter())
}
}
impl<'s, S: Copy, V> IntoIterator for &'s VarStack<'s, S, V> {
type Item = (S, &'s V);
type IntoIter = VarIter<'s, S, V>;
#[inline(always)]
fn into_iter(self) -> VarIter<'s, S, V> {
VarIter(self.0.iter())
}
}
pub struct VarIter<'s, S, V>(pub RefIter<'s, VarStackEntry<S, V>>);
impl<S, V> marker::Copy for VarIter<'_, S, V> {}
impl<S, V> clone::Clone for VarIter<'_, S, V> {
fn clone(&self) -> Self {
Self(self.0)
}
}
impl<S: Copy + fmt::Debug, V: fmt::Debug> fmt::Debug for VarIter<'_, S, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(*self).finish()
}
}
impl<'s, S: Copy, V> Iterator for VarIter<'s, S, V> {
type Item = (S, &'s V);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|vse| (vse.name, &vse.value))
}
}