duster/src/renderer/breadcrumb_tree.rs

86 lines
2.4 KiB
Rust
Raw Normal View History

use crate::renderer::context_element::IntoContextElement;
use std::borrow::Borrow;
use std::rc::Rc;
pub struct BreadcrumbTree<'a> {
parent: Option<&'a BreadcrumbTree<'a>>,
element: BreadcrumbTreeElement<'a>,
}
#[derive(Clone, Debug)]
pub enum BreadcrumbTreeElement<'a> {
// Using Rc so that when we need to create BreadcrumbTrees with
// the same BreadcrumbTreeElement but a different parent (for
// example, when inserting behind the tail), we don't need to the
// copy the already owned/malloc'd data.
Owned(Rc<dyn IntoContextElement>),
Borrowed(&'a dyn IntoContextElement),
}
impl<'a> BreadcrumbTree<'a> {
pub fn new(parent: Option<&'a BreadcrumbTree>, element: BreadcrumbTreeElement<'a>) -> Self {
BreadcrumbTree {
parent: parent,
element: element,
}
}
pub fn get_ice(&self) -> &dyn IntoContextElement {
self.element.borrow()
}
pub fn get_parent(&self) -> Option<&BreadcrumbTree> {
self.parent
}
pub fn get_element(&self) -> &BreadcrumbTreeElement<'a> {
&self.element
}
pub fn ice_iter(&'a self) -> impl Iterator<Item = &dyn IntoContextElement> {
self.breadcrumb_iter().map(|b| b.get_ice())
}
pub fn breadcrumb_iter(&'a self) -> BreadcrumbTreeIterator<'a> {
BreadcrumbTreeIterator(Some(self))
}
pub fn clone_to_new_parent(&self, parent: Option<&'a BreadcrumbTree>) -> Self {
// TODO: Maybe not needed anymore?
BreadcrumbTree {
parent: parent,
element: self.element.clone(),
}
}
}
impl<'a> Borrow<dyn IntoContextElement + 'a> for BreadcrumbTreeElement<'a> {
fn borrow(&self) -> &(dyn IntoContextElement + 'a) {
match self {
BreadcrumbTreeElement::Owned(ice) => ice.as_ref(),
BreadcrumbTreeElement::Borrowed(ice) => *ice,
}
}
}
impl<'a> IntoIterator for &'a BreadcrumbTree<'a> {
type Item = &'a BreadcrumbTree<'a>;
type IntoIter = BreadcrumbTreeIterator<'a>;
fn into_iter(self) -> BreadcrumbTreeIterator<'a> {
self.breadcrumb_iter()
}
}
pub struct BreadcrumbTreeIterator<'a>(Option<&'a BreadcrumbTree<'a>>);
impl<'a> Iterator for BreadcrumbTreeIterator<'a> {
type Item = &'a BreadcrumbTree<'a>;
fn next(&mut self) -> Option<Self::Item> {
let ret = self.0;
self.0 = self.0.map(|node| node.get_parent()).flatten();
ret
}
}