//! This file provides a default implementation for the //! [`Forest`][crate::Forest] trait. use super::*; use graph::{error::Error as GraphError, ALGraph, Graph}; use std::collections::{hash_set::Iter, HashMap, HashSet}; #[derive(Debug, Clone)] pub struct DefaultForest { graph: ALGraph, vertex_labels: HashMap, edge_labels: HashMap<(usize, usize), EdgeLabel>, plugins: HashSet, plugouts: HashSet, } impl Default for DefaultForest { fn default() -> Self { Self { graph: Default::default(), vertex_labels: Default::default(), edge_labels: Default::default(), plugins: Default::default(), plugouts: Default::default(), } } } impl Graph for DefaultForest { type Iter<'a> = ::Iter<'a> where Self: 'a; fn is_empty(&self) -> bool { self.graph.is_empty() } fn nodes_len(&self) -> usize { self.graph.nodes_len() } fn children_of(&self, node_id: usize) -> Result, GraphError> { self.graph.children_of(node_id) } fn degree(&self, node_id: usize) -> Result { self.graph.degree(node_id) } fn is_empty_node(&self, node_id: usize) -> Result { self.graph.is_empty_node(node_id) } fn has_edge(&self, source: usize, target: usize) -> Result { self.graph.has_edge(source, target) } fn replace_by_builder(&mut self, _builder: impl graph::Builder) { unimplemented!() } } #[derive(Debug)] pub struct LabelIter<'a> { set_iter: Iter<'a, usize>, } impl<'a> Iterator for LabelIter<'a> { type Item = usize; fn next(&mut self) -> Option { self.set_iter.next().copied() } fn size_hint(&self) -> (usize, Option) { self.set_iter.size_hint() } } impl<'a> ExactSizeIterator for LabelIter<'a> { fn len(&self) -> usize { self.set_iter.len() } } impl<'a> From> for LabelIter<'a> { fn from(set_iter: Iter<'a, usize>) -> Self { Self { set_iter } } } impl Forest for DefaultForest { type PluginIter<'a> = LabelIter<'a> where Self: 'a; type PlugoutIter<'a> = LabelIter<'a> where Self: 'a; fn plugins(&self) -> Self::PluginIter<'_> { self.plugins.iter().into() } fn plugouts(&self) -> Self::PlugoutIter<'_> { self.plugouts.iter().into() } fn plug(&mut self, other: &Self) -> Result<(), Error> { // PLAN: Produce a BuilderMut, adjust the indices for edges, // and then add edges between plugs. // // Since I cannot touch the underlying nodes directly, I have // to add the nodes and edges individually. todo!() } fn vertex_label(&self, node_id: usize) -> Result, Error> { if node_id >= self.nodes_len() { return Err(Error::IndexOutOfBounds(node_id, self.nodes_len())); } Ok(self.vertex_labels.get(&node_id).copied()) } fn edge_label(&self, source: usize, target: usize) -> Result, Error> { if source >= self.nodes_len() { return Err(Error::IndexOutOfBounds(source, self.nodes_len())); } if target >= self.nodes_len() { return Err(Error::IndexOutOfBounds(target, self.nodes_len())); } Ok(self.edge_labels.get(&(source, target)).copied()) } }