From fcd4ecceb1e544345efd6e7c53b5d036e7a72efa Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 5 Feb 2019 10:44:40 -0500 Subject: [PATCH] Add interior_mutability example --- .idea/misc.xml | 1 + .idea/rust.iml | 5 +++ .idea/workspace.xml | 71 ++++++++++++++++++++++++---------- interior_mutability/Cargo.toml | 7 ++++ interior_mutability/src/lib.rs | 70 +++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 21 deletions(-) create mode 100644 interior_mutability/Cargo.toml create mode 100644 interior_mutability/src/lib.rs diff --git a/.idea/misc.xml b/.idea/misc.xml index 465fbc7..98a09f5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -26,6 +26,7 @@ + diff --git a/.idea/rust.iml b/.idea/rust.iml index 73d9872..c67cafa 100644 --- a/.idea/rust.iml +++ b/.idea/rust.iml @@ -106,6 +106,10 @@ + + + + @@ -118,6 +122,7 @@ + diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 5369e4f..1799341 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,6 +5,7 @@ + + + + + + + + + + + + + + - - + + @@ -92,6 +106,7 @@ @@ -165,7 +180,7 @@ - + @@ -232,16 +247,6 @@ - - - + + + @@ -272,10 +287,10 @@ + + - - @@ -307,6 +322,9 @@ + + + @@ -329,7 +347,7 @@ - + @@ -731,10 +749,21 @@ + + + + + + + + + + + - - + + diff --git a/interior_mutability/Cargo.toml b/interior_mutability/Cargo.toml new file mode 100644 index 0000000..64c2b3f --- /dev/null +++ b/interior_mutability/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "interior_mutability" +version = "0.1.0" +authors = ["Timothy Warren "] +edition = "2018" + +[dependencies] diff --git a/interior_mutability/src/lib.rs b/interior_mutability/src/lib.rs new file mode 100644 index 0000000..a541f54 --- /dev/null +++ b/interior_mutability/src/lib.rs @@ -0,0 +1,70 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: 'a + Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> + where T: Messenger { + pub fn new(messenger: &T, max: usize) -> LimitTracker { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >=1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger.send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger.send("Warning: You've used up over 75% of your quota!"); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + // RefCell wraps the vector in a way that it can be mutably + // referenced at runtime + sent_messages: RefCell>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { sent_messages: RefCell::new(vec![]) } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + // If we tried to create another mutable borrow in this scope, + // it would cause a panic. Same rules as at compile time. + self.sent_messages.borrow_mut().push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + + assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); + } +}