use List::{Cons, Nil}; use std::cell::RefCell; use std::ops::Deref; use std::rc::{Rc, Weak}; //enum List { // Cons(i32, Rc), // Nil, //} //#[derive(Debug)] //enum List { // Cons(Rc>, Rc), // Nil, //} #[derive(Debug)] enum List { Cons(i32, RefCell>), Nil, } impl List { fn tail(&self) -> Option<&RefCell>> { match self { Cons(_, item) => Some(item), Nil => None, } } } //enum List { // Cons(i32, Box), // Nil, //} struct MyBox(T); impl MyBox { fn new(x: T) -> MyBox { MyBox(x) } } impl Deref for MyBox { type Target = T; fn deref(&self) -> &T { &self.0 } } struct CustomSmartPointer { data: String, } impl Drop for CustomSmartPointer { fn drop(&mut self) { println!("Dropped `{}`", self.data); } } #[derive(Debug)] struct Node { value: i32, parent: RefCell>, children: RefCell>>, } fn main() { // let x = 5; // let y = MyBox::new(x); // // assert_eq!(5, x); // assert_eq!(5, *y); // let m = MyBox::new(String::from("world")); // hello(&m); // let c = CustomSmartPointer { data: String::from("my stuff") }; // drop(c); // let d = CustomSmartPointer { data: String::from("other stuff") }; // println!("created."); // let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); // dbg!(Rc::strong_count(&a)); // let b = Cons(3, Rc::clone(&a)); // dbg!(Rc::strong_count(&a)); // { // let c = Cons(4, Rc::clone(&a)); // dbg!(Rc::strong_count(&a)); // } // dbg!(Rc::strong_count(&a)); // let value = Rc::new(RefCell::new(5)); // // let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); // // let b = Cons(Rc::new(RefCell::new(6)), Rc::clone(&a)); // let c = Cons(Rc::new(RefCell::new(10)), Rc::clone(&a)); // // *value.borrow_mut() += 10; // // dbg!(a); // dbg!(b); // dbg!(c); // let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil)))); // dbg!(Rc::strong_count(&a)); // dbg!(a.tail()); // let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a)))); // dbg!(Rc::strong_count(&a)); // dbg!(Rc::strong_count(&b)); // dbg!(b.tail()); // // if let Some(link) = a.tail() { // *link.borrow_mut() = Rc::clone(&b); // } // // dbg!(Rc::strong_count(&b)); // dbg!(Rc::strong_count(&a)); //dbg!(a.tail()); // stack overflow let leaf = Rc::new(Node { value: 3, parent: RefCell::new(Weak::new()), children: RefCell::new(vec![]), }); println!("leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf),); { let branch = Rc::new(Node { value: 5, parent: RefCell::new(Weak::new()), children: RefCell::new(vec![Rc::clone(&leaf)]), }); *leaf.parent.borrow_mut() = Rc::downgrade(&branch); println!( "branch strong = {}, weak = {}", Rc::strong_count(&branch), Rc::weak_count(&branch), ); println!( "leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf), ); } println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); println!( "leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf), ); } fn hello(name: &str) { println!("hiya {}", name); } pub trait Messenger { fn send(&self, msg: &str); } pub struct LimitTracker<'a, T: 'a + Messenger> { messenger: &'a T, value: usize, max: usize, } impl<'a, T> LimitTracker<'a, T> where T: Messenger { pub fn new(messenger: &T, max: usize) -> LimitTracker { LimitTracker { messenger, value: 0, max, } } pub fn set_value(&mut self, value: usize) { self.value = value; let percentage_of_max = self.value as f64 / self.max as f64; if percentage_of_max >= 1.0 { self.messenger.send("over quota"); } else if percentage_of_max >= 0.9 { self.messenger.send("90% of quota"); } else if percentage_of_max >= 0.75 { self.messenger.send("75% of quota"); } } } #[cfg(test)] mod tests { use super::*; use std::cell::RefCell; struct MockMessenger { sent_messages: RefCell>, } impl MockMessenger { fn new() -> MockMessenger { MockMessenger { sent_messages: RefCell::new(vec![]) } } } impl Messenger for MockMessenger { fn send(&self, message: &str) { self.sent_messages.borrow_mut().push(String::from(message)); } } #[test] fn sends_75() { let mock_messenger = MockMessenger::new(); let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); limit_tracker.set_value(80); assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); } }