## 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 too X% of your quote"` 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 too 40% of your quote")
("Warning", "you have used up over 90% of your quota! Proceeds with precaution")
("Error", "you are over your quota!")
[
  "Info: you are using up too 40% of your quote",
  "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)
