Remove the Clone constraint from T

This commit is contained in:
Savanni D'Gerinel 2023-10-20 20:17:33 -04:00
parent fbf6a9e76e
commit 2ceccbf38d
1 changed files with 30 additions and 14 deletions

View File

@ -3,21 +3,25 @@
//! //!
//! This surely already exists. I am created it to test my own ability to do things in Rust. //! 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)] #[derive(Debug)]
pub enum Tree<T: Clone> { pub enum Tree<T> {
Empty, Empty,
Root(Node<T>), Root(Node<T>),
} }
impl<T: Clone> Default for Tree<T> { impl<T> Default for Tree<T> {
fn default() -> Self { fn default() -> Self {
Tree::Empty Tree::Empty
} }
} }
impl<T: Clone> Tree<T> { impl<T> Tree<T> {
pub fn set_value(&mut self, value: T) { pub fn set_value(&mut self, value: T) {
*self = Tree::Root(Node::new(value)); *self = Tree::Root(Node::new(value));
} }
@ -41,7 +45,7 @@ impl<T: Clone> Tree<T> {
return Some(node.clone()); return Some(node.clone());
} }
for child in node.children() { for child in node.children().iter() {
queue.push_back(child.clone()) queue.push_back(child.clone())
} }
} }
@ -54,16 +58,25 @@ impl<T: Clone> Tree<T> {
// make the visible objects mutable. // make the visible objects mutable.
// //
// This feels like cheating the type system. // This feels like cheating the type system.
#[derive(Clone, Debug)] //
pub struct Node<T: Clone>(Rc<RefCell<Node_<T>>>); // 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<T>(Rc<RefCell<Node_<T>>>);
impl<T> Clone for Node<T> {
fn clone(&self) -> Self {
Node(Rc::clone(&self.0))
}
}
#[derive(Debug)] #[derive(Debug)]
struct Node_<T: Clone> { struct Node_<T> {
value: T, value: T,
children: Vec<Node<T>>, children: Vec<Node<T>>,
} }
impl<T: Clone> Node<T> { impl<T> Node<T> {
pub fn new(value: T) -> Self { pub fn new(value: T) -> Self {
Self(Rc::new(RefCell::new(Node_ { Self(Rc::new(RefCell::new(Node_ {
value, value,
@ -71,12 +84,15 @@ impl<T: Clone> Node<T> {
}))) })))
} }
pub fn value<'a>(&'a self) -> T { // I am copying the value because I don't have a mechanism for keeping the borrow ref active.
self.0.borrow().value.clone() // 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<T> {
Ref::map(self.0.borrow(), |v| &v.value)
} }
pub fn children<'a>(&'a self) -> Vec<Node<T>> { pub fn children<'a>(&'a self) -> Ref<Vec<Node<T>>> {
self.0.borrow().children.clone() Ref::map(self.0.borrow(), |v| &v.children)
} }
pub fn add_child_node(&self, child: Node<T>) { pub fn add_child_node(&self, child: Node<T>) {
@ -110,7 +126,7 @@ mod tests {
let n = Node::new(15); let n = Node::new(15);
n.add_child_value(20); 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)))]); // assert_eq!(n.children(), vec![Rc::new(RefCell::new(Node::new(20)))]);
} }
} }