You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4.6 KiB

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:

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,

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:

$ 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