use crate::renderer::context_element::IntoContextElement; use std::borrow::Borrow; pub trait BreadcrumbTree { fn get_ice(&self) -> &dyn IntoContextElement; fn get_parent(&self) -> Option<&dyn BreadcrumbTree>; } pub struct BreadcrumbTreeNode<'a, C: IntoContextElement> { parent: Option<&'a dyn BreadcrumbTree>, element: BreadcrumbTreeNodeElement<'a, C>, } enum BreadcrumbTreeNodeElement<'a, C: IntoContextElement> { Owned(C), Borrowed(&'a C), } impl<'a, C: IntoContextElement> BreadcrumbTreeNode<'a, C> { pub fn ice_iter(&'a self) -> IceTreeIterator<'a> { IceTreeIterator(Some(self)) } pub fn breadcrumb_iter(&'a self) -> BreadcrumbTreeIterator<'a> { BreadcrumbTreeIterator(Some(self)) } } impl<'a, C: IntoContextElement> Borrow<dyn IntoContextElement + 'a> for BreadcrumbTreeNodeElement<'a, C> { fn borrow(&self) -> &(dyn IntoContextElement + 'a) { match self { BreadcrumbTreeNodeElement::Owned(ice) => ice, BreadcrumbTreeNodeElement::Borrowed(ice) => *ice, } } } impl<'a, C: IntoContextElement> BreadcrumbTree for BreadcrumbTreeNode<'a, C> { fn get_ice(&self) -> &dyn IntoContextElement { self.element.borrow() } fn get_parent(&self) -> Option<&dyn BreadcrumbTree> { self.parent } } pub struct IceTreeIterator<'a>(Option<&'a dyn BreadcrumbTree>); impl<'a> Iterator for IceTreeIterator<'a> { type Item = &'a dyn IntoContextElement; fn next(&mut self) -> Option<Self::Item> { let ret = self.0; self.0 = self.0.map(|node| node.get_parent()).flatten(); ret.map(|node| node.get_ice()) } } impl<'a, C: IntoContextElement> IntoIterator for &'a BreadcrumbTreeNode<'a, C> { type Item = &'a dyn BreadcrumbTree; type IntoIter = BreadcrumbTreeIterator<'a>; fn into_iter(self) -> BreadcrumbTreeIterator<'a> { self.breadcrumb_iter() } } pub struct BreadcrumbTreeIterator<'a>(Option<&'a dyn BreadcrumbTree>); impl<'a> Iterator for BreadcrumbTreeIterator<'a> { type Item = &'a dyn BreadcrumbTree; fn next(&mut self) -> Option<Self::Item> { let ret = self.0; self.0 = self.0.map(|node| node.get_parent()).flatten(); ret } }