forked from root/public
lee
3 years ago
24 changed files with 1239 additions and 0 deletions
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "borrow_box" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "borrow_box_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"borrow_box", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "borrow_box_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
borrow_box = { path = "../../../../rust-piscine-solutions/borrow_box"} |
@ -0,0 +1,91 @@
|
||||
use borrow_box::*; |
||||
|
||||
fn main() { |
||||
let mut game = Game::new(0, String::from("Joao"), String::from("Susana"), 5); |
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Same score! tied", 0)
|
||||
|
||||
game.update_score(String::from("Joao")); |
||||
game.update_score(String::from("Joao")); |
||||
game.update_score(String::from("Susana")); |
||||
game.update_score(String::from("Susana")); |
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Same score! tied", 2)
|
||||
|
||||
game.update_score(String::from("Joao")); |
||||
// this one will not count because it already 5 games played, the nbr_of_games
|
||||
game.update_score(String::from("Susana")); |
||||
|
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Joao", 3)
|
||||
|
||||
println!("{:?}", game.delete()); |
||||
// output : "game deleted: id -> 0"
|
||||
|
||||
// game.read_winner();
|
||||
// this will give error
|
||||
// because the game was dropped, no longer exists on the heap
|
||||
} |
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
fn create_games() -> Vec<Box<Game>> { |
||||
vec![ |
||||
Game::new(0, String::from("player1"), String::from("player2"), 1), |
||||
Game::new(1, String::from("Alice"), String::from("Mark"), 3), |
||||
Game::new(2, String::from("Jack"), String::from("Miller"), 5) |
||||
] |
||||
} |
||||
|
||||
#[test] |
||||
fn test_create() { |
||||
let games = create_games(); |
||||
assert_eq!(*games[0], Game {id: 0, p1: (String::from("player1"), 0), p2: (String::from("player2"), 0), nbr_of_games: 1}); |
||||
assert_eq!(*games[1], Game {id: 1, p1: (String::from("Alice"), 0), p2: (String::from("Mark"), 0), nbr_of_games: 3}); |
||||
assert_eq!(*games[2], Game {id: 2, p1: (String::from("Jack"), 0), p2: (String::from("Miller"), 0), nbr_of_games: 5}); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_update_and_read() { |
||||
let mut games = create_games(); |
||||
games[0].update_score(String::from("player1")); |
||||
assert_eq!(games[0].read_winner(), (String::from("player1"), 1)); |
||||
|
||||
games[0].update_score(String::from("player2")); |
||||
// this will stay the same because the nbr_of_games is 1 so if one
|
||||
// of the players wins just once it will no longer increment the score
|
||||
assert_eq!(games[0].read_winner(), (String::from("player1"), 1)); |
||||
|
||||
games[2].update_score(String::from("Jack")); |
||||
games[2].update_score(String::from("Jack")); |
||||
games[2].update_score(String::from("Miller")); |
||||
games[2].update_score(String::from("Miller")); |
||||
// tie between players
|
||||
assert_eq!(games[2].read_winner(), (String::from("Same score! tied"), 2)); |
||||
|
||||
games[2].update_score(String::from("Jack")); |
||||
assert_eq!(games[2].read_winner(), (String::from("Jack"), 3)); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_delete() { |
||||
let game = Game::new(0, String::from("Alice"), String::from("Mark"), 3); |
||||
let game1 = Game::new(23, String::from("Jack"), String::from("Miller"), 1); |
||||
|
||||
assert_eq!(game.delete(), String::from("game deleted: id -> 0")); |
||||
assert_eq!(game1.delete(), String::from("game deleted: id -> 23")); |
||||
} |
||||
|
||||
// #[test]
|
||||
// #[should_panic]
|
||||
// fn test_delete_ownership() {
|
||||
// let game = new(0, String::from("Alice"), String::from("Mark"), 3);
|
||||
// {
|
||||
// let a = &game;
|
||||
// // error! cant destroy boxed while the inner value is borrowed later in scope
|
||||
// delete(game);
|
||||
// read_winner(&a);
|
||||
// }
|
||||
// }
|
||||
} |
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "box_it" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "box_it_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"box_it", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "box_it_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
box_it = { path = "../../../../rust-piscine-solutions/box_it"} |
@ -0,0 +1,56 @@
|
||||
use box_it::*; |
||||
|
||||
fn main() { |
||||
let new_str = String::from("5.5k 8.9k 32"); |
||||
|
||||
// creating a variable and we save it in the Heap
|
||||
let a_h = transform_and_save_on_heap(new_str); |
||||
println!("Box value : {:?}", &a_h); |
||||
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_h))); |
||||
|
||||
let a_b_v = take_value_ownership(a_h); |
||||
println!("value : {:?}", &a_b_v); |
||||
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_b_v))); |
||||
// whenever the box, in this case "a_h", goes out of scope it will be deallocated, freed
|
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
use std::mem; |
||||
|
||||
#[test] |
||||
fn test_transform() { |
||||
let new_str = String::from("5.5k 8.9k 32"); |
||||
let new_str_1 = String::from("6.8k 13.5k"); |
||||
let new_str_2 = String::from("20.3k 3.8k 7.7k 992"); |
||||
|
||||
let a = transform_and_save_on_heap(new_str); |
||||
let b = transform_and_save_on_heap(new_str_1); |
||||
let c = transform_and_save_on_heap(new_str_2); |
||||
|
||||
assert_eq!(a, Box::new(vec![5500, 8900, 32])); |
||||
assert_eq!(b, Box::new(vec![6800, 13500])); |
||||
assert_eq!(c, Box::new(vec![20300, 3800, 7700, 992])); |
||||
assert_eq!(mem::size_of_val(&a), 8); |
||||
assert_eq!(mem::size_of_val(&b), 8); |
||||
assert_eq!(mem::size_of_val(&c), 8); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_take_value_from_box() { |
||||
let new_str = String::from("5.5k 8.9k 32"); |
||||
let new_str_1 = String::from("6.8k 13.5k"); |
||||
let new_str_2 = String::from("20.3k 3.8k 7.7k 992"); |
||||
let a = take_value_ownership(transform_and_save_on_heap(new_str)); |
||||
let b = take_value_ownership(transform_and_save_on_heap(new_str_1)); |
||||
let c = take_value_ownership(transform_and_save_on_heap(new_str_2)); |
||||
|
||||
assert_eq!(a, vec![5500, 8900, 32]); |
||||
assert_eq!(b, vec![6800, 13500]); |
||||
assert_eq!(c, vec![20300, 3800, 7700, 992]); |
||||
assert_eq!(mem::size_of_val(&a), 24); |
||||
assert_eq!(mem::size_of_val(&b), 24); |
||||
assert_eq!(mem::size_of_val(&c), 24); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "box_recursion" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "box_recursion_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"box_recursion", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "box_recursion_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
box_recursion = { path = "../../../../rust-piscine-solutions/box_recursion"} |
@ -0,0 +1,98 @@
|
||||
use box_recursion::*; |
||||
|
||||
fn main() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.add_worker(String::from("Manager"), String::from("Monica")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Ana")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Alice")); |
||||
println!("{:?}", list); |
||||
|
||||
println!("{:?}", list.search_worker()); |
||||
|
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
println!("{:?}", list); |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
#[test] |
||||
fn test_new() { |
||||
let list = WorkEnvironment::new(); |
||||
assert!(list.grade.is_none()); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_one_worker() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.remove_worker(); |
||||
assert!(list.grade.is_none()); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_two_workers() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.add_worker(String::from("Manager"), String::from("Monica")); |
||||
list.remove_worker(); |
||||
|
||||
assert_eq!(list.grade.as_ref().unwrap().worker_type, "CEO"); |
||||
assert_eq!(list.grade.as_ref().unwrap().worker_name, "Marie"); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_more_workers() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.add_worker(String::from("Manager"), String::from("Monica")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Ana")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Alice")); |
||||
list.remove_worker(); |
||||
|
||||
assert_eq!(list.grade.as_ref().unwrap().worker_type, "Normal Worker"); |
||||
assert_eq!(list.grade.as_ref().unwrap().worker_name, "Ana"); |
||||
|
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
assert_eq!(list.grade.as_ref().unwrap().worker_type, "CEO"); |
||||
assert_eq!(list.grade.as_ref().unwrap().worker_name, "Marie"); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_search() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.add_worker(String::from("Manager"), String::from("Monica")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Ana")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Alice")); |
||||
|
||||
assert_eq!( |
||||
list.search_worker().unwrap(), |
||||
(String::from("Alice"), String::from("Normal Worker")) |
||||
); |
||||
|
||||
list.remove_worker(); |
||||
assert_eq!( |
||||
list.search_worker().unwrap(), |
||||
(String::from("Ana"), String::from("Normal Worker")) |
||||
); |
||||
|
||||
list.remove_worker(); |
||||
assert_eq!( |
||||
list.search_worker().unwrap(), |
||||
(String::from("Monica"), String::from("Manager")) |
||||
); |
||||
|
||||
list.remove_worker(); |
||||
assert_eq!( |
||||
list.search_worker().unwrap(), |
||||
(String::from("Marie"), String::from("CEO")) |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "drop_the_thread" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "drop_the_thread_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"drop_the_thread", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "drop_the_thread_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
drop_the_thread = { path = "../../../../rust-piscine-solutions/drop_the_thread"} |
@ -0,0 +1,87 @@
|
||||
use drop_the_thread::*; |
||||
use std::rc::Rc; |
||||
|
||||
fn main() { |
||||
let worker = Workers::new(); |
||||
let (id, thread) = worker.new_worker(String::from("command")); |
||||
let (id1, thread1) = worker.new_worker(String::from("command1")); |
||||
|
||||
thread.skill(); |
||||
|
||||
println!("{:?}", (worker.is_dropped(id), id, &worker.drops)); |
||||
// output: (true, 0, Cell { value: 1 })
|
||||
|
||||
thread1.skill(); |
||||
println!("{:?}", (worker.is_dropped(id1), id1, &worker.drops)); |
||||
// output: (true, 1, Cell { value: 2 })
|
||||
|
||||
let (id2, thread2) = worker.new_worker(String::from("command2")); |
||||
let thread2 = Rc::new(thread2); |
||||
let thread2_clone = thread2.clone(); |
||||
|
||||
// thread2_clone.skill();
|
||||
drop(thread2_clone); |
||||
|
||||
println!("{:?}", (worker.is_dropped(id2), id2, &worker.drops, Rc::strong_count(&thread2))); |
||||
// (false, 2, Cell { value: 2 }, 1)
|
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
use std::rc::Rc; |
||||
|
||||
#[test] |
||||
fn test_is_dropped_and_drops() { |
||||
let worker = Workers::new(); |
||||
let (pid, thread) = worker.new_worker(String::from("gnome-shell")); |
||||
let (pid0, thread0) = worker.new_worker(String::from("i3")); |
||||
let (pid1, thread1) = worker.new_worker(String::from("shell")); |
||||
let (pid2, thread2) = worker.new_worker(String::from("spotify")); |
||||
|
||||
thread.skill(); |
||||
assert_eq!(worker.drops.get(), 1_usize); |
||||
thread0.skill(); |
||||
|
||||
assert!(worker.is_dropped(pid), "{} should have been dropped", pid); |
||||
assert!(worker.is_dropped(pid0), "{} should have been dropped", pid0); |
||||
assert!(!worker.is_dropped(pid1), "{} should not have been dropped", pid1); |
||||
assert!(!worker.is_dropped(pid2), "{} should not have been dropped", pid2); |
||||
|
||||
assert_eq!(worker.drops.get(), 2_usize); |
||||
|
||||
thread1.skill(); |
||||
thread2.skill(); |
||||
|
||||
assert_eq!(worker.drops.get(), 4_usize); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_using_rc() { |
||||
// will create a new reference to the thread
|
||||
// this will test the following
|
||||
// if we drop the cloned value the RC will decrease
|
||||
// but the thread will not be dropped!
|
||||
let worker = Workers::new(); |
||||
let (_, thread) = worker.new_worker(String::from("Xorg")); |
||||
let thread = Rc::new(thread); |
||||
let thread_clone = thread.clone(); |
||||
|
||||
assert_eq!(Rc::strong_count(&thread), 2); |
||||
|
||||
drop(thread_clone); |
||||
|
||||
assert_eq!(Rc::strong_count(&thread), 1); |
||||
} |
||||
|
||||
#[test] |
||||
#[should_panic(expected = "0 is already dropped")] |
||||
fn test_drop_same_thread() { |
||||
// test if we drop the same thread after it was already been dropped
|
||||
let worker = Workers::new(); |
||||
let (pid, thread) = worker.new_worker(String::from("gsd-rfkill")); |
||||
let thread_clone = thread.clone(); |
||||
thread.skill(); |
||||
thread_clone.skill(); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "how_many_references" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "how_many_references_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"how_many_references", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "how_many_references_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
how_many_references = { path = "../../../../rust-piscine-solutions/how_many_references"} |
@ -0,0 +1,103 @@
|
||||
use how_many_references::*; |
||||
|
||||
fn main() { |
||||
let a = Rc::new(String::from("a")); |
||||
let b = Rc::new(String::from("b")); |
||||
let c = Rc::new(String::from("c")); |
||||
|
||||
let a1 = Rc::new(String::from("a")); |
||||
|
||||
let mut new_node = Node::new(vec![a.clone()]); |
||||
new_node.add_ele(b.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
new_node.add_ele(c.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
|
||||
println!("a: {:?}", how_many_references(&a)); |
||||
println!("b: {:?}", how_many_references(&b)); |
||||
println!("c: {:?}", how_many_references(&c)); |
||||
new_node.rm_all_ref(a1.clone()); |
||||
new_node.rm_all_ref(a.clone()); |
||||
|
||||
println!("a: {:?}", how_many_references(&a)); |
||||
println!("b: {:?}", how_many_references(&b)); |
||||
println!("c: {:?}", how_many_references(&c)); |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
#[test] |
||||
fn test_add_ele() { |
||||
let a = Rc::new(String::from("a")); |
||||
let b = Rc::new(String::from("b")); |
||||
let c = Rc::new(String::from("c")); |
||||
|
||||
let mut new_node = Node::new(vec![a.clone()]); |
||||
new_node.add_ele(a.clone()); |
||||
new_node.add_ele(b.clone()); |
||||
new_node.add_ele(c.clone()); |
||||
|
||||
assert_eq!(new_node.value, vec![a.clone(), a, b, c]); |
||||
} |
||||
#[test] |
||||
fn test_how_many_references() { |
||||
let a = Rc::new(String::from("a")); |
||||
let b = Rc::new(String::from("b")); |
||||
let c = Rc::new(String::from("c")); |
||||
let d = Rc::new(String::from("d")); |
||||
let mut new_node = Node::new(vec![]); |
||||
new_node.add_ele(b.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
new_node.add_ele(c.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
|
||||
assert_eq!(how_many_references(&d), 1); |
||||
assert_eq!(how_many_references(&a), 3); |
||||
assert_eq!(how_many_references(&b), 2); |
||||
assert_eq!(how_many_references(&c), 2); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_rm_all_ref() { |
||||
let a = Rc::new(String::from("a")); |
||||
let b = Rc::new(String::from("b")); |
||||
let c = Rc::new(String::from("c")); |
||||
let d = Rc::new(String::from("d")); |
||||
|
||||
let a1 = Rc::new(String::from("a")); |
||||
let b1 = Rc::new(String::from("b")); |
||||
let c1 = Rc::new(String::from("c")); |
||||
let d1 = Rc::new(String::from("d")); |
||||
let mut new_node = Node::new(vec![ |
||||
d.clone(), |
||||
d.clone(), |
||||
b.clone(), |
||||
a.clone(), |
||||
c.clone(), |
||||
a.clone(), |
||||
d.clone(), |
||||
]); |
||||
|
||||
new_node.rm_all_ref(a1.clone()); |
||||
assert_eq!(how_many_references(&a), 3); |
||||
new_node.rm_all_ref(a.clone()); |
||||
assert_eq!(how_many_references(&a), 1); |
||||
|
||||
new_node.rm_all_ref(b1.clone()); |
||||
assert_eq!(how_many_references(&b), 2); |
||||
new_node.rm_all_ref(b.clone()); |
||||
assert_eq!(how_many_references(&b), 1); |
||||
|
||||
new_node.rm_all_ref(c1.clone()); |
||||
assert_eq!(how_many_references(&c), 2); |
||||
new_node.rm_all_ref(c.clone()); |
||||
assert_eq!(how_many_references(&c), 1); |
||||
|
||||
new_node.rm_all_ref(d1.clone()); |
||||
assert_eq!(how_many_references(&d), 4); |
||||
new_node.rm_all_ref(d.clone()); |
||||
assert_eq!(how_many_references(&d), 1); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
# This file is automatically @generated by Cargo. |
||||
# It is not intended for manual editing. |
||||
[[package]] |
||||
name = "ref_cell" |
||||
version = "0.1.0" |
||||
|
||||
[[package]] |
||||
name = "ref_cell_test" |
||||
version = "0.1.0" |
||||
dependencies = [ |
||||
"ref_cell", |
||||
] |
@ -0,0 +1,10 @@
|
||||
[package] |
||||
name = "ref_cell_test" |
||||
version = "0.1.0" |
||||
authors = ["lee <lee-dasilva@hotmail.com>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
ref_cell = { path = "../../../../rust-piscine-solutions/ref_cell"} |
@ -0,0 +1,158 @@
|
||||
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()); |
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
use super::*; |
||||
|
||||
#[test] |
||||
fn test_module() { |
||||
#[derive(Clone, Debug)] |
||||
struct TestMs { |
||||
value: Rc<usize>, |
||||
ms: RefCell<Vec<String>>, |
||||
correct: Vec<String>, |
||||
} |
||||
|
||||
impl Logger for TestMs { |
||||
fn warning(&self, message: &str) { |
||||
self.ms.borrow_mut().push(message.to_string()); |
||||
} |
||||
fn info(&self, message: &str) { |
||||
self.ms.borrow_mut().push(message.to_string()); |
||||
} |
||||
fn error(&self, message: &str) { |
||||
self.ms.borrow_mut().push(message.to_string()); |
||||
} |
||||
} |
||||
|
||||
let l = TestMs { |
||||
value: Rc::new(115), |
||||
ms: RefCell::new(vec![]), |
||||
correct: vec![ |
||||
String::from("Info: you are using up too 40% of your quote"), |
||||
String::from("Warning: you have used up over 80% of your quota! Proceeds with precaution"), |
||||
String::from("Error: you are over your quota!") |
||||
], |
||||
}; |
||||
|
||||
let track = Tracker::new(&l, 5); |
||||
let _a = l.value.clone(); |
||||
track.peek(&l.value); // 40%
|
||||
let _a1 = l.value.clone(); |
||||
let _a2 = l.value.clone(); |
||||
track.set_value(&l.value); // 80%
|
||||
let _a3 = l.value.clone(); |
||||
track.set_value(&l.value); // 100%
|
||||
|
||||
for (i, v) in l.ms.into_inner().iter().enumerate() { |
||||
assert_eq!(v, &l.correct[i]) |
||||
} |
||||
} |
||||
|
||||
#[test] |
||||
fn test_module_usage_hasmap() { |
||||
let log = Worker::new(1000); |
||||
let track = Tracker::new(&log, 12); |
||||
let _clone_test = log.track_value.clone(); |
||||
let _clone_test1 = log.track_value.clone(); |
||||
let _clone_test2 = log.track_value.clone(); |
||||
let _clone_test3 = log.track_value.clone(); |
||||
let _clone_test4 = log.track_value.clone(); |
||||
let _clone_test5 = log.track_value.clone(); |
||||
let _clone_test6 = log.track_value.clone(); |
||||
let _clone_test7 = log.track_value.clone(); |
||||
|
||||
// warning: 75% of the quota
|
||||
track.set_value(&log.track_value); |
||||
assert_eq!(log.mapped_messages.borrow().get("Warning").unwrap(), "you have used up over 75% of your quota! Proceeds with precaution"); |
||||
|
||||
let _clone_test8 = log.track_value.clone(); |
||||
|
||||
// warning: 83% of the quota <- most resent of the messages last onw to be added to the hashmap
|
||||
track.set_value(&log.track_value); |
||||
assert_eq!(log.mapped_messages.borrow().get("Warning").unwrap(), "you have used up over 83% of your quota! Proceeds with precaution"); |
||||
|
||||
// info: 83%
|
||||
track.peek(&log.track_value); |
||||
assert_eq!(log.mapped_messages.borrow().get("Info").unwrap(), "you are using up too 83% of your quote"); |
||||
|
||||
let _clone_test9 = log.track_value.clone(); |
||||
// info: 91%
|
||||
track.peek(&log.track_value); |
||||
assert_eq!(log.mapped_messages.borrow().get("Info").unwrap(), "you are using up too 91% of your quote"); |
||||
|
||||
let _clone_test10 = log.track_value.clone(); |
||||
// error: passed the quota
|
||||
track.set_value(&log.track_value); |
||||
assert_eq!(log.mapped_messages.borrow().get("Error").unwrap(), "you are over your quota!"); |
||||
} |
||||
|
||||
#[test] |
||||
fn test_module_usage_vector() { |
||||
let correct = vec![ |
||||
"Info: you are using up too 40% of your quote", |
||||
"Warning: you have used up over 80% of your quota! Proceeds with precaution", |
||||
"Info: you are using up too 80% of your quote", "Error: you are over your quota!" |
||||
]; |
||||
let log = Worker::new(1); |
||||
let track = Tracker::new(&log, 5); |
||||
let _a = log.track_value.clone(); |
||||
// info: 40%
|
||||
track.peek(&log.track_value); |
||||
let _a1 = log.track_value.clone(); |
||||
let _a2 = log.track_value.clone(); |
||||
|
||||
// warning: 80%
|
||||
track.set_value(&log.track_value); |
||||
// info: 80%
|
||||
track.peek(&log.track_value); |
||||
let _a3 = log.track_value.clone(); |
||||
|
||||
// error: passed the quota
|
||||
track.set_value(&log.track_value); |
||||
|
||||
for (i, v) in log.all_messages.into_inner().iter().enumerate() { |
||||
assert_eq!(v, correct[i]); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,83 @@
|
||||
## borrow box |
||||
|
||||
### Instructions |
||||
|
||||
You will have to create a **CRUD** functionality. Therefore creating the following functions : |
||||
|
||||
- `new`, that receives two players and initializes them with a name and a score. This functions should |
||||
return the structure wrapped in a Box. |
||||
|
||||
- `read_winner`, returns a tuple with the name and the score of the player who is winning. |
||||
In case none of the players are winning, it should return the same tuple with the string "Same score! tied" and the tied score. |
||||
|
||||
- `update_score`, that receives the name of a player. |
||||
This function should increment the score of the player. The score should only be increased if it does not pass the `nbr_of_games`. |
||||
Example: if the nbr_of_games is 3 then the game should be best out of three. So if one play as 2 wins then |
||||
he is the winner and the function should not increase the score anymore for either players. |
||||
|
||||
- `delete`, that takes the ownership of the boxed game and returning a string : "Game deleted: id -> 0". |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
#[derive(Debug, Clone, Eq, PartialEq)] |
||||
pub struct Game { |
||||
// expected public fields |
||||
} |
||||
impl Game { |
||||
pub fn new(i: u32, pl1: String, pl2: String, n: u16) -> Box<Game> {} |
||||
pub fn read_winner(&self) -> (String, u16) {} |
||||
pub fn update_score(&mut self, user_name: String) {} |
||||
pub fn delete(self) -> String {} |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut game = Game::create_game(0, String::from("Joao"), String::from("Susana"), 5); |
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Same score! tied", 0) |
||||
|
||||
game.update_score(String::from("Joao")); |
||||
game.update_score(String::from("Joao")); |
||||
game.update_score(String::from("Susana")); |
||||
game.update_score(String::from("Susana")); |
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Same score! tied", 2) |
||||
|
||||
game.update_score(String::from("Joao")); |
||||
// this one will not count because it already 5 games played, the nbr_of_games |
||||
game.update_score(String::from("Susana")); |
||||
|
||||
println!("{:?}", game.read_winner()); |
||||
// output : ("Joao", 3) |
||||
|
||||
game.delete(); |
||||
println!("{:?}", game.delete()); |
||||
// output : "game deleted: id -> 0" |
||||
|
||||
// game.read_winner(); |
||||
// this will give error |
||||
// because the game was dropped, no longer exists on the heap |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
("Same score! tied", 0) |
||||
("Same score! tied", 2) |
||||
("Joao", 3) |
||||
"game deleted: id -> 0" |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
|
||||
### Notions |
||||
|
||||
- https://doc.rust-lang.org/book/ch15-01-box.html |
@ -0,0 +1,53 @@
|
||||
## box_it |
||||
|
||||
### Instructions |
||||
|
||||
Create the following functions: |
||||
|
||||
- `transform_and_save_on_heap`, that receives a string with a number (that can or not have a k (kilo) suffix) |
||||
and transforms those numbers into `u32` and inserts it into a vector that must be saved in the heap using **Box**. |
||||
|
||||
- `take_value_ownership`, that takes the value (unboxed value) form the box and returns it |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
pub fn transform_and_save_on_heap(s: String) -> Box<Vec<u32>> {} |
||||
pub fn take_value_ownership(a: Box<Vec<u32>>) -> Vec<u32> {} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let new_str = String::from("5.5k 8.9k 32"); |
||||
|
||||
// creating a variable and we save it in the Heap |
||||
let a_h = transform_and_save_on_heap(new_str); |
||||
println!("Box value : {:?}", &a_h); |
||||
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_h))); |
||||
|
||||
let a_b_v = take_value_ownership(a_h); |
||||
println!("value : {:?}", &a_b_v); |
||||
println!("size occupied in the stack : {:?} bytes", (std::mem::size_of_val(&a_b_v))); |
||||
// whenever the box, in this case "a_h", goes out of scope it will be deallocated, freed |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
Box value : [6800, 13500] |
||||
size occupied in the stack : 8 bytes |
||||
value : [6800, 13500] |
||||
size occupied in the stack : 24 bytes |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
### Notions |
||||
|
||||
- https://doc.rust-lang.org/book/ch15-00-smart-pointers.html |
||||
- https://doc.rust-lang.org/book/ch15-01-box.html |
@ -0,0 +1,79 @@
|
||||
## box_recursion |
||||
|
||||
### Instructions |
||||
|
||||
Using the given code create the following functions: |
||||
|
||||
- `new` that will initialize the `WorkEnvironment` as `None` |
||||
- `add_worker`, that receives two strings, one being the type of worker and the other the name of the worker. |
||||
- `remove_worker`, that removes the last worker that was placed in the `WorkEnvironment`, this functions should |
||||
return a `Option` with the name of the worker. |
||||
- `search_worker`, that return a tuple with the name and type of worker. |
||||
|
||||
You must also create a type called `Link` this will be the connection of the structures `WorkEnvironment` and `Worker`. |
||||
Do not forget that this will be a recursion type and it must point to `None` if there is no workers. |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
pub struct WorkEnvironment { |
||||
pub grade: Link, |
||||
} |
||||
|
||||
pub type Link = |
||||
|
||||
pub struct Worker { |
||||
pub worker_type: String, |
||||
pub worker_name: String, |
||||
pub next_worker: Link, |
||||
} |
||||
|
||||
impl WorkEnvironment { |
||||
pub fn new() -> WorkEnvironment {} |
||||
pub fn add_worker(&mut self, t: String, name: String) {} |
||||
pub fn remove_worker(&mut self) -> Option<String> {} |
||||
pub fn search_worker(&self) -> Option<(String, String)> {} |
||||
} |
||||
|
||||
|
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let mut list = WorkEnvironment::new(); |
||||
list.add_worker(String::from("CEO"), String::from("Marie")); |
||||
list.add_worker(String::from("Manager"), String::from("Monica")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Ana")); |
||||
list.add_worker(String::from("Normal Worker"), String::from("Alice")); |
||||
println!("{:?}", list); |
||||
|
||||
println!("{:?}", list.search_worker()); |
||||
|
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
list.remove_worker(); |
||||
println!("{:?}", list); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
WorkEnvironment { grade: Some(Worker { worker_type: "Normal Worker", worker_name: "Alice", next_worker: Some(Worker { worker_type: "Normal Worker", worker_name: "Ana", next_worker: Some(Worker { worker_type: "Manager", worker_name: "Monica", next_worker: Some(Worker { worker_type: "CEO", worker_name: "Marie", next_worker: None }) }) }) }) } |
||||
Some(("Alice", "Normal Worker")) |
||||
WorkEnvironment { grade: None } |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
### Notions |
||||
|
||||
- https://doc.rust-lang.org/rust-by-example/custom_types/enum.html |
||||
- https://doc.rust-lang.org/book/ch15-01-box.html |
||||
- https://doc.rust-lang.org/std/option/ |
||||
- https://doc.rust-lang.org/book/ch15-01-box.html |
@ -0,0 +1,109 @@
|
||||
## drop_the_thread |
||||
|
||||
### Instructions |
||||
|
||||
"Interior mutability is a design pattern in Rust that allows you to mutate data even when there are immutable references to that data" |
||||
|
||||
You must create a Drop checker API. For this you must create: |
||||
|
||||
- Two structures: |
||||
- `Workers` that will have two fields: |
||||
- `drops` that will save the number of dropped threads |
||||
- `states` that will save a state of multiple threads. |
||||
If the thread is not dropped, the state will be false otherwise true. |
||||
- `Thread` that will have the following fields: |
||||
- `pid`, the id of the thread |
||||
- `cmd`, the name of the thread |
||||
- `parent`, that will be the link to the structure `Workers` (Tip: this must be a reference to the structure Workers) |
||||
|
||||
- Implementation of each structure: |
||||
- `Workers` : |
||||
- `new`, that creates a default worker |
||||
- `new_worker`, that returns a tuple with the `pid` and a new `Thread`, |
||||
this function must receive a `String` being the `cmd` |
||||
- `is_dropped`, that receives a `pid` and returns a `bool` that indicates the state of the thread by using the `pid` |
||||
- `track_worker`, it should return a `usize`, that will be the last available index of the `states` vector, being the new next thread |
||||
- `add_drop`, this function must be **called by the `Drop` trait**. It will receive a `pid` that will be used to change the |
||||
state of the thread. If the state of that thread is `true` then it will panic with the message ("Cannot drop {}, because its already dropped", pid). |
||||
Otherwise it should change the state to true and increment the `drops` field by one. |
||||
|
||||
- `Thread`: |
||||
- `new_thread`, that initializes a new thread |
||||
- `skill`, that drops the thread |
||||
|
||||
- You must implement for the structure `Thread` the `Drop` trait. In this trait you must call the function `add_drop` so that the state of the thread changes |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
use std::cell::{RefCell, Cell}; |
||||
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)] |
||||
pub struct Workers { |
||||
pub drops: Cell<usize>, |
||||
pub state: RefCell<Vec<bool>> |
||||
} |
||||
|
||||
impl Workers { |
||||
pub fn new() -> Workers {} |
||||
pub fn new_worker(&self, c: String) -> (usize, Thread) {} |
||||
pub fn track_worker(&self) -> usize {} |
||||
pub fn is_dropped(&self, id: usize) -> bool {} |
||||
pub fn add_drop(&self, id: usize) {} |
||||
} |
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)] |
||||
pub struct Thread<'a> { |
||||
// expected public fields |
||||
} |
||||
|
||||
impl<'a> Thread<'a> { |
||||
pub fn new_thread(p: usize, c: String, t: &'a Workers) -> Thread {} |
||||
pub fn skill(self) {} |
||||
} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
use std::rc::Rc; |
||||
|
||||
fn main() { |
||||
let worker = Workers::new(); |
||||
let (id, thread) = worker.new_worker(String::from("command")); |
||||
let (id1, thread1) = worker.new_worker(String::from("command1")); |
||||
|
||||
thread.skill(); |
||||
|
||||
println!("{:?}", (worker.is_dropped(id), id, &worker.drops)); |
||||
|
||||
thread1.skill(); |
||||
println!("{:?}", (worker.is_dropped(id1), id1, &worker.drops)); |
||||
|
||||
let (id2, thread2) = worker.new_worker(String::from("command2")); |
||||
let thread2 = Rc::new(thread2); |
||||
let thread2_clone = thread2.clone(); |
||||
|
||||
drop(thread2_clone); |
||||
|
||||
println!("{:?}", (worker.is_dropped(id2), id2, &worker.drops, Rc::strong_count(&thread2))); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
(true, 0, Cell { value: 1 }) |
||||
(true, 1, Cell { value: 2 }) |
||||
(false, 2, Cell { value: 2 }, 1) |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
### Notions |
||||
|
||||
- https://doc.bccnsoft.com/docs/rust-1.36.0-docs-html/std/ops/trait.Drop.html |
||||
- https://doc.rust-lang.org/std/cell/struct.RefCell.html |
||||
- https://doc.rust-lang.org/book/ch15-05-interior-mutability.html |
@ -0,0 +1,78 @@
|
||||
## how many references |
||||
|
||||
### Instructions |
||||
|
||||
Create the following functions : |
||||
|
||||
- `add_ele` that adds an element to the value in the `Node` |
||||
- `how_many_references` that returns how many times the value is referenced in the code |
||||
- `rm_all_ref` that receives a `Rc<String>` and removes all elements from the vector that |
||||
are equal to that value, this should only happen if the two Rcs point to the same allocation |
||||
|
||||
### Expected Function |
||||
|
||||
```rust |
||||
pub use std::rc::Rc; |
||||
|
||||
pub struct Node { |
||||
pub value: Vec<Rc<String>>, |
||||
} |
||||
|
||||
impl Node { |
||||
pub fn new(value: Vec<Rc<String>>) -> Node { |
||||
Node { value: value } |
||||
} |
||||
pub fn add_ele(&mut self, v: Rc<String>) {} |
||||
pub fn rm_all_ref(&mut self, v: Rc<String>) {} |
||||
} |
||||
|
||||
pub fn how_many_references(value: &Rc<String>) -> usize {} |
||||
``` |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
fn main() { |
||||
let a = Rc::new(String::from("a")); |
||||
let b = Rc::new(String::from("b")); |
||||
let c = Rc::new(String::from("c")); |
||||
|
||||
let a1 = Rc::new(String::from("a")); |
||||
|
||||
let mut new_node = Node::new(vec![a.clone()]); |
||||
new_node.add_ele(b.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
new_node.add_ele(c.clone()); |
||||
new_node.add_ele(a.clone()); |
||||
|
||||
println!("a: {:?}", how_many_references(&a)); |
||||
println!("b: {:?}", how_many_references(&b)); |
||||
println!("c: {:?}", how_many_references(&c)); |
||||
new_node.rm_all_ref(a1.clone()); |
||||
new_node.rm_all_ref(a.clone()); |
||||
|
||||
println!("a: {:?}", how_many_references(&a)); |
||||
println!("b: {:?}", how_many_references(&b)); |
||||
println!("c: {:?}", how_many_references(&c)); |
||||
} |
||||
``` |
||||
|
||||
And its output: |
||||
|
||||
```console |
||||
student@ubuntu:~/[[ROOT]]/test$ cargo run |
||||
a: 4 |
||||
b: 2 |
||||
c: 2 |
||||
a: 1 |
||||
b: 2 |
||||
c: 2 |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
### Notions |
||||
|
||||
- https://doc.rust-lang.org/book/ch15-04-rc.html |
||||
- https://doc.rust-lang.org/std/rc/struct.Rc.html |
@ -0,0 +1,112 @@
|
||||
## ref_cell |
||||
|
||||
### Instructions |
||||
|
||||
### 1º part |
||||
|
||||
Create a module called `messenger`. This module will be able to inform a user of how much references of a given value he is using. |
||||
The main objective for this module is to limit how many times a value is referenced. |
||||
|
||||
For the module you must create the following: |
||||
|
||||
- A trait `Logger` that implements three functions: `warning`, `info`, `error`. All function should receive a reference to themselves and a string literal. |
||||
|
||||
```rust |
||||
fn warning(&self, msg: &str); |
||||
fn info(&self, msg: &str); |
||||
fn error(&self, msg: &str); |
||||
``` |
||||
|
||||
- A structure called `Tracker`, that must have the fields: `logger` being a reference to the `Logger`, `value` being the count of how many times the value was referenced, |
||||
`max` being the max count of references the actual value can achieve. |
||||
|
||||
- An implementation of three functions that are associated to the `Tracker` structure: |
||||
- `new` that will initialize the structure |
||||
- `set_value` that sets the value to the `Tracker` structure and writes to the trait functions. This should be done comparing the **max** and the number of referenced of the actual value. |
||||
If the percentage is equal or greater to 100% of the limit usage, it should write **"Error: you are over your quota!"** to the `error` function |
||||
If the percentage is equal or greater to 70% of the limit usage, it should write **("Warning: you have used up over {}% of your quota! Proceeds with precaution", <calculated_percentage>)** to the `warning` function |
||||
- `peek` that will take a peek of how much usage the variable already has. It should write **("Info: you are using up too {}% of your quote", <calculated_percentage>)** to the `info` function |
||||
|
||||
### 2ª part |
||||
|
||||
Afterwards you must use the module `messenger` and create the following: |
||||
|
||||
- A structure `Worker` that has the fields: |
||||
- `track_value` this will be the value that will be tracked by the tracker. |
||||
- `mapped_messages` that will have the latest messages. This must be a HashMap with the key being the type of message |
||||
sent by the logger (info, error or warning) and the value being the message |
||||
- `all_messages` that will be a vector of all messages sent. |
||||
- A `new` function that initializes the structure `Worker` |
||||
- 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 fields of the structure Worker. |
||||
|
||||
You must use **interior mutability**, this means it must be able to mutate data even when there are immutable references to that data. |
||||
|
||||
So the user doesn't need to use the keyword `mut` (tip: RefCell) |
||||
|
||||
### Usage |
||||
|
||||
Here is a program to test your function |
||||
|
||||
```rust |
||||
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 |
||||
student@ubuntu:~/[[ROOT]]/test$ 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!" |
||||
] |
||||
student@ubuntu:~/[[ROOT]]/test$ |
||||
``` |
||||
|
||||
### Notions |
||||
|
||||
- https://doc.rust-lang.org/std/cell/struct.RefCell.html |
||||
- https://doc.rust-lang.org/std/rc/struct.Rc.html |
Loading…
Reference in new issue