1+ use std:: { cell:: RefCell , rc:: Rc } ;
2+ use List :: { Cons , Nil } ;
3+
4+ #[ derive( Debug ) ]
5+ enum List {
6+ Cons ( Rc < RefCell < i32 > > , Rc < List > ) ,
7+ Nil ,
8+ }
9+
10+ pub fn intmut ( ) {
11+ let value = Rc :: new ( RefCell :: new ( 5 ) ) ;
12+
13+ let a = Rc :: new ( Cons ( Rc :: clone ( & value) , Rc :: new ( Nil ) ) ) ;
14+ println ! ( "a before = {a:?}" ) ;
15+
16+ let b = Cons ( Rc :: new ( RefCell :: new ( 3 ) ) , Rc :: clone ( & a) ) ;
17+ let c = Cons ( Rc :: new ( RefCell :: new ( 4 ) ) , Rc :: clone ( & a) ) ;
18+
19+ * value. borrow_mut ( ) += 10 ;
20+
21+ println ! ( "a after = {a:?}" ) ;
22+ println ! ( "b after = {b:?}" ) ;
23+ println ! ( "c after = {c:?}" ) ;
24+ }
25+
26+ pub trait Messenger {
27+ fn send ( & self , msg : & str ) ;
28+ }
29+
30+ pub struct LimitTracker < ' a , T : Messenger > {
31+ messenger : & ' a T ,
32+ value : usize ,
33+ max : usize ,
34+ }
35+
36+ impl < ' a , T > LimitTracker < ' a , T >
37+ where
38+ T : Messenger ,
39+ {
40+ pub fn new ( messenger : & ' a T , max : usize ) -> LimitTracker < ' a , T > {
41+ LimitTracker {
42+ messenger,
43+ value : 0 ,
44+ max,
45+ }
46+ }
47+
48+ pub fn set_value ( & mut self , value : usize ) {
49+ self . value = value;
50+
51+ let percentage_of_max = self . value as f64 / self . max as f64 ;
52+
53+ if percentage_of_max >= 1.0 {
54+ self . messenger . send ( "Error: You are over your quota!" ) ;
55+ } else if percentage_of_max >= 0.9 {
56+ self . messenger
57+ . send ( "Urgent warning: You've used up over 90% of your quota!" ) ;
58+ } else if percentage_of_max >= 0.75 {
59+ self . messenger
60+ . send ( "Warning: You've used up over 75% of your quota!" ) ;
61+ }
62+ }
63+ }
64+
65+ #[ cfg( test) ]
66+ mod tests {
67+ use super :: * ;
68+ use std:: cell:: RefCell ;
69+
70+ struct MockMessenger {
71+ sent_messages : RefCell < Vec < String > > ,
72+ }
73+
74+ impl MockMessenger {
75+ fn new ( ) -> MockMessenger {
76+ MockMessenger {
77+ sent_messages : RefCell :: new ( vec ! [ ] ) ,
78+ }
79+ }
80+ }
81+
82+ impl Messenger for MockMessenger {
83+ fn send ( & self , message : & str ) {
84+ self . sent_messages . borrow_mut ( ) . push ( String :: from ( message) ) ;
85+ }
86+ }
87+
88+ #[ test]
89+ fn it_sends_an_over_75_percent_warning_message ( ) {
90+ let mock_messenger = MockMessenger :: new ( ) ;
91+ let mut limit_tracker = LimitTracker :: new ( & mock_messenger, 100 ) ;
92+
93+ limit_tracker. set_value ( 80 ) ;
94+
95+ assert_eq ! ( mock_messenger. sent_messages. borrow( ) . len( ) , 1 ) ;
96+ }
97+ }
0 commit comments