use std::fmt::{Display, Formatter}; #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct ID(usize); #[derive(Debug, PartialEq)] pub struct Syntree<T> { id: ID, value: T, children: Vec<Syntree<T>>, } // Complete the implementation // Hint: Start with seek_node_mut impl<'a, T> Syntree<T> { pub fn new(value: T, id: ID) -> Syntree<T> { todo!() } pub fn push_node(&mut self, parent_id: ID, new_node: Syntree<T>) -> Result<(), String> { todo!() } pub fn prepend_node(&mut self, parent_id: ID, new_node: Syntree<T>) -> Result<(), String> { todo!() } pub fn insert_node( &mut self, parent_id: ID, index: usize, new_node: Syntree<T>, ) -> Result<(), String> { todo!() } // Anmerkung: `'a` Is ein Lebenszeit angabe für die Referenzen // Hier wird einfach nur explizit gesagt: Solange `self` lebt, lebt auch die Referenz im Rückgabewert pub fn seek_node(&'a self, id: &ID) -> Option<&'a Syntree<T>> { if self.id == *id { Some(self) } else { for child in &self.children { if let Some(result) = child.seek_node(id) { return Some(result); } } None } } pub fn seek_node_mut(&'a mut self, id: &ID) -> Option<&'a mut Syntree<T>> { todo!() } } impl<T: Display> Syntree<T> { pub fn print(&self) -> String { if self.children.is_empty() { format!("{}", self.value) } else { format!( "{}-[{}]", self.value, &self .children .iter() .map(|tn| tn.print()) .collect::<Vec<String>>() .join(",") ) } } } impl<T: Display> Display for Syntree<T> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "({})", self.print()) } } #[cfg(test)] mod tests { use super::*; #[test] fn fill_tree() -> Result<(), String> { let mut tree = Syntree::new(0, ID(0)); for child in 1..3 { let child_id = ID(child); let mut child = Syntree::new(child, child_id); for grandchild in 1..3 { let id = grandchild * 10; child.prepend_node(child_id, Syntree::new(id, ID(id)))?; } tree.push_node(ID(0), child)?; } println!("{}", tree); assert_eq!(String::from("0-[1-[20,10],2-[20,10]]"), tree.print()); Ok(()) } #[test] fn fill_tree_words() -> Result<(), String> { let mut tree = Syntree::new(to_s("root"), ID(0)); for (child_id, child) in ["first", "second", "third"].iter().map(to_s).enumerate() { let child_id = ID(child_id); let mut child = Syntree::new(child, child_id); if child_id.0 == 0 { let descendant = Syntree::new(to_s("A"), ID(4)); child.push_node(child_id, descendant)?; let descendant = Syntree::new(to_s("B"), ID(5)); child.push_node(ID(4), descendant)?; let descendant = Syntree::new(to_s("C"), ID(6)); child.push_node(ID(5), descendant)?; } tree.push_node(ID(0), child)?; } println!("{}", tree); assert_eq!( String::from("root-[first-[A-[B-[C]]],second,third]"), tree.print() ); Ok(()) } fn to_s<T: Display>(value: T) -> String { format!("{}", value) } #[test] fn node_id_not_found() -> Result<(), String> { let mut tree = Syntree::new(0, ID(0)); let child_id = ID(1); let child = Syntree::new(1, child_id); tree.push_node(ID(0), child)?; let child_id = ID(2); let child = Syntree::new(3, child_id); assert!(tree.push_node(ID(5), child).is_err()); Ok(()) } }