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 @@
+
@@ -14,11 +15,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
@@ -92,6 +106,7 @@
+
@@ -165,7 +180,7 @@
-
+
@@ -232,16 +247,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -252,13 +257,23 @@
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
@@ -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);
+ }
+}