study_example/smart_pointer/
refcell_pointer.rs1use std::borrow::BorrowMut;
2use std::cell::RefCell;
3use std::rc::Rc;
4pub trait Messager {
5 fn send(&self, msg: &str);
6}
7
8pub struct LimitTracker<'a, T: Messager> {
9 messager: &'a T,
10 value: usize,
11 max: usize,
12}
13
14impl<'a, T> LimitTracker<'a, T>
15where
16 T: Messager,
17{
18 pub fn new(messager: &'a T, max: usize) -> LimitTracker<'a, T> {
19 LimitTracker {
20 messager,
21 value: 0,
22 max,
23 }
24 }
25
26 pub fn set_value(&mut self, value: usize) {
27 self.value = value;
28 let percentage_of_max = self.value as f64 / self.max as f64;
29 if percentage_of_max >= 1.0 {
30 self.messager.send("Error: You are over your quota!");
31 } else if percentage_of_max >= 0.9 {
32 self.messager
33 .send("Urgent warning: You've used up over 90% of your quota!");
34 } else if percentage_of_max >= 0.75 {
35 self.messager
36 .send("Warning: You've used up over 75% of your quota!");
37 }
38 }
39}
40
41struct MockMessager {
42 sent_message: std::cell::RefCell<Vec<String>>,
43}
44
45impl MockMessager {
46 fn new() -> MockMessager {
47 MockMessager {
48 sent_message: std::cell::RefCell::new(vec![]),
49 }
50 }
51}
52
53impl Messager for MockMessager {
54 fn send(&self, msg: &str) {
55 self.sent_message.borrow_mut().push(String::from(msg));
58 self.sent_message.borrow_mut().push(String::from(msg));
59 let mut borrow1 = self.sent_message.borrow_mut();
60 borrow1.push(String::from(msg));
63 }
65}
66
67#[derive(Debug)]
68enum List {
69 Cons(Rc<RefCell<i32>>, Rc<List>),
70 Nil,
71}
72fn cons_modify_usage() {
74 let value = Rc::new(RefCell::new(5));
75 let a = Rc::new(List::Cons(Rc::clone(&value), Rc::new(List::Nil)));
76 let b = List::Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
77 let c = List::Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
78 let mut value_borrow = (*value).borrow_mut();
79 *value_borrow += 100;
80 println!("value: {:?}", value);
81 println!("a after = {:?}", a);
82 println!("b after = {:?}", b);
83 println!("c after = {:?}", c);
84}
85pub fn refcell_pointer_study() {
93 let mock_messager = MockMessager::new();
94 let mut limit_tracker = LimitTracker::new(&mock_messager, 100);
95 limit_tracker.set_value(80);
96 println!(
97 "mock message len: {}",
98 mock_messager.sent_message.borrow().len()
99 );
100 cons_modify_usage();
101}