From 2ceccbf38d36189c959e53b793150e8a65ad9bd9 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Fri, 20 Oct 2023 20:17:33 -0400 Subject: [PATCH] Remove the Clone constraint from T --- tree/src/lib.rs | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/tree/src/lib.rs b/tree/src/lib.rs index 8835d82..4cfef40 100644 --- a/tree/src/lib.rs +++ b/tree/src/lib.rs @@ -3,21 +3,25 @@ //! //! This surely already exists. I am created it to test my own ability to do things in Rust. -use std::{cell::RefCell, collections::VecDeque, rc::Rc}; +use std::{ + cell::{Ref, RefCell}, + collections::VecDeque, + rc::Rc, +}; #[derive(Debug)] -pub enum Tree { +pub enum Tree { Empty, Root(Node), } -impl Default for Tree { +impl Default for Tree { fn default() -> Self { Tree::Empty } } -impl Tree { +impl Tree { pub fn set_value(&mut self, value: T) { *self = Tree::Root(Node::new(value)); } @@ -41,7 +45,7 @@ impl Tree { return Some(node.clone()); } - for child in node.children() { + for child in node.children().iter() { queue.push_back(child.clone()) } } @@ -54,16 +58,25 @@ impl Tree { // make the visible objects mutable. // // This feels like cheating the type system. -#[derive(Clone, Debug)] -pub struct Node(Rc>>); +// +// However, since I've moved the RefCell inside of the node, I can borrow the node multiple times +// in a traversal function and I can make changes to nodes that I find. +#[derive(Debug)] +pub struct Node(Rc>>); + +impl Clone for Node { + fn clone(&self) -> Self { + Node(Rc::clone(&self.0)) + } +} #[derive(Debug)] -struct Node_ { +struct Node_ { value: T, children: Vec>, } -impl Node { +impl Node { pub fn new(value: T) -> Self { Self(Rc::new(RefCell::new(Node_ { value, @@ -71,12 +84,15 @@ impl Node { }))) } - pub fn value<'a>(&'a self) -> T { - self.0.borrow().value.clone() + // I am copying the value because I don't have a mechanism for keeping the borrow ref active. + // My next step is to figure out how to keep the borrow ref active so that I don't have to + // clone the item. Then I could drop the Clone constraint. + pub fn value<'a>(&'a self) -> Ref { + Ref::map(self.0.borrow(), |v| &v.value) } - pub fn children<'a>(&'a self) -> Vec> { - self.0.borrow().children.clone() + pub fn children<'a>(&'a self) -> Ref>> { + Ref::map(self.0.borrow(), |v| &v.children) } pub fn add_child_node(&self, child: Node) { @@ -110,7 +126,7 @@ mod tests { let n = Node::new(15); n.add_child_value(20); - assert_eq!(n.value(), 15); + assert_eq!(*n.value(), 15); // assert_eq!(n.children(), vec![Rc::new(RefCell::new(Node::new(20)))]); } }