organic/src/parser/list.rs
Tom Alexander 66d10a7a1b
Started switching over to a stack-based context tree with global settings.
This change should hopefully allow for matchers to have captured borrowed values, it should eliminate the use of heap-allocated reference counting on the context nodes, and it adds in a global settings struct for passing around values that do not change during parsing.
2023-09-02 18:20:10 -04:00

67 lines
1.3 KiB
Rust

use std::fmt::Debug;
#[derive(Debug, Clone)]
pub struct List<'parent, T> {
data: T,
parent: Link<'parent, T>,
}
type Link<'parent, T> = Option<&'parent List<'parent, T>>;
impl<'parent, T> List<'parent, T> {
pub fn new(first_item: T) -> Self {
Self {
data: first_item,
parent: None,
}
}
pub fn get_data(&self) -> &T {
&self.data
}
pub fn get_parent(&'parent self) -> Link<'parent, T> {
self.parent
}
pub fn iter(&self) -> Iter<'_, T> {
Iter { next: Some(self) }
}
}
pub trait ListType<'parent, T> {
fn push(&'parent self, item: T) -> List<'parent, T>;
}
impl<'parent, T> ListType<'parent, T> for List<'parent, T> {
fn push(&'parent self, item: T) -> Self {
Self {
data: item,
parent: Some(self),
}
}
}
impl<'parent, T> ListType<'parent, T> for Link<'parent, T> {
fn push(&'parent self, item: T) -> List<'parent, T> {
List {
data: item,
parent: *self,
}
}
}
pub struct Iter<'a, T> {
next: Link<'a, T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let ret = self.next.map(|link| link.get_data());
self.next = self.next.map(|link| link.get_parent()).flatten();
ret
}
}