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), 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 { 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 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 { let ret = self.0; self.0 = self.0.map(|node| node.get_parent()).flatten(); ret } }