## ref_cell ### Instructions #### First part (messenger.rs) Create a module named `messenger`. This module will be able to inform a user of how many references of a given value they are using. The main objective of this module is to limit how many times a value is referenced. For this module the following must be created: Implement `Logger`: a trait which implements the following three functions: ```rust fn warning(&self, msg: &str); fn info(&self, msg: &str); fn error(&self, msg: &str); ``` Implement the `Tracker` structure with the following fields: - `logger`: a reference to `Logger`. - `value`: the count of how many times the value was referenced. It should not exceed `max`. - `max`: the max count of references. Add the following associated functions to `Tracker`: - `new`: that initializes the structure. - `set_value`: that sets the `value`. It should compare the number of references to `value` and `max` to work out the percentage used. It should write to the following traits if it exceeds the specified usage percentage: - percentage >= 100%: `"Error: you are over your quota!"` should be written to `error`. - percentage >= 70% and percentage < 100%: `"Warning: you have used up over X% of your quota! Proceeds with precaution"` should be written to `warning`, where `X` should be replaced with the calculated percentage. - `peek`: that will take a peek at how much usage the variable already has. It should write `"Info: you are using up to X% of your quota"` to the `info` trait function. `X` should be replaced with the calculated percentage. ### Second part (lib.rs) Now that you've created `messenger`, you can now create the following: Create the `Worker` structure with the following fields: - `track_value`: which is the value that will be tracked by the tracker. - `mapped_messages`: that will store the latest messages from the `Logger` trait functions. This will be a HashMap. The key will represent the type of message (`info`, `error` or `warning`), and the value will be the actual message. - `all_messages`: that will be a vector of **all** messages sent. Create the following associated functions for `Worker`: - `new`: that initializes a `Worker` structure. - `Logger`: to use the trait `Logger`, you must implement it for the `Worker` structure. Each function (`warning`, `error` and `info`) must insert the message to the respective field of the `Worker` structure. You must use **interior mutability**, this means it must be possible to mutate data, even when there are immutable references to that data. Consequently, the user will not need to use the keyword `mut`. _tip:_ RefCell. ### Usage Here is a program to test your function, ```rust use ref_cell::*; fn main() { // initialize the worker let logger = Worker::new(1); // initialize the tracker, with the max number of // called references as 10 let track = Tracker::new(&logger, 10); let _a = logger.track_value.clone(); // |\ let _a1 = logger.track_value.clone(); // | -> increase the Rc to 4 references let _a2 = logger.track_value.clone(); // |/ // take a peek of how much we already used from our quota track.peek(&logger.track_value); let _b = logger.track_value.clone(); // |\ let _b1 = logger.track_value.clone(); // | -> increase the Rc to 8 references let _b2 = logger.track_value.clone(); // | / let _b3 = logger.track_value.clone(); // |/ // this will set the value and making a verification of // how much we already used of our quota track.set_value(&logger.track_value); let _c = logger.track_value.clone(); // | -> increase the Rc to 9 references // this will set the value and making a verification of // how much we already used of our quota track.set_value(&logger.track_value); let _c1 = logger.track_value.clone(); // | -> increase the Rc to 10 references, this will be the limit track.set_value(&logger.track_value); for (k ,v) in logger.mapped_messages.into_inner() { println!("{:?}", (k ,v)); } println!("{:?}", logger.all_messages.into_inner()); } ``` And its output: ```console $ cargo run ("Info", "you are using up to 40% of your quota") ("Warning", "you have used up over 90% of your quota! Proceeds with precaution") ("Error", "you are over your quota!") [ "Info: you are using up to 40% of your quota", "Warning: you have used up over 80% of your quota! Proceeds with precaution", "Warning: you have used up over 90% of your quota! Proceeds with precaution", "Error: you are over your quota!" ] $ ``` ### Notions - [std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html) - [Struct std::rc::Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html)