Add interior_mutability example
This commit is contained in:
parent
9347fea052
commit
fcd4ecceb1
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@ -26,6 +26,7 @@
|
||||
<cargoProject FILE="$PROJECT_DIR$/add/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/smart_pointers/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/reference_counting/Cargo.toml" />
|
||||
<cargoProject FILE="$PROJECT_DIR$/interior_mutability/Cargo.toml" />
|
||||
</component>
|
||||
<component name="ComposerJsonPluginSettings">
|
||||
<unboundedVersionInspectionSettings>
|
||||
|
5
.idea/rust.iml
generated
5
.idea/rust.iml
generated
@ -106,6 +106,10 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/reference_counting/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/reference_counting/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/reference_counting/benches" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/interior_mutability/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/interior_mutability/examples" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/interior_mutability/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/interior_mutability/benches" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/add/add-one/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/add/adder/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/adder/target" />
|
||||
@ -118,6 +122,7 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/functions/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/generics/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/guessing_game/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/interior_mutability/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/lifetimes/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/loops/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/minigrep/target" />
|
||||
|
71
.idea/workspace.xml
generated
71
.idea/workspace.xml
generated
@ -5,6 +5,7 @@
|
||||
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/rust.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/rust.iml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/reference_counting/src/main.rs" beforeDir="false" afterPath="$PROJECT_DIR$/reference_counting/src/main.rs" afterDir="false" />
|
||||
</list>
|
||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
@ -14,11 +15,24 @@
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/interior_mutability/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="672">
|
||||
<caret line="55" column="69" selection-start-line="55" selection-start-column="69" selection-end-line="55" selection-end-column="69" />
|
||||
<folding>
|
||||
<element signature="e#1104#1105#0" expanded="true" />
|
||||
<element signature="e#1144#1145#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/reference_counting/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="224">
|
||||
<caret line="14" column="13" selection-start-line="14" selection-start-column="13" selection-end-line="14" selection-end-column="13" />
|
||||
<state relative-caret-position="320">
|
||||
<caret line="20" column="15" selection-start-line="20" selection-start-column="15" selection-end-line="20" selection-end-column="15" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@ -92,6 +106,7 @@
|
||||
<option value="$PROJECT_DIR$/add/add-one/src/lib.rs" />
|
||||
<option value="$PROJECT_DIR$/smart_pointers/src/lib.rs" />
|
||||
<option value="$PROJECT_DIR$/smart_pointers/src/main.rs" />
|
||||
<option value="$PROJECT_DIR$/interior_mutability/src/lib.rs" />
|
||||
<option value="$PROJECT_DIR$/reference_counting/src/main.rs" />
|
||||
</list>
|
||||
</option>
|
||||
@ -165,7 +180,7 @@
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="JavaScriptWeakerCompletionTypeGuess" value="true" />
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549380100372" />
|
||||
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549381304560" />
|
||||
<property name="javascript.nodejs.core.library.configured.version" value="7.1.0" />
|
||||
<property name="js.eslint.eslintPackage" value="$USER_HOME$/.yarn-config/global/node_modules/.bin/eslint" />
|
||||
<property name="js.eslint.nodeInterpreter" value="project" />
|
||||
@ -232,16 +247,6 @@
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Test calling_next_directly" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="test --package closures --lib calling_next_directly -- --exact" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/closures" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Test lib::tests (1)" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="test --package minigrep_v2 --lib tests" />
|
||||
@ -252,13 +257,23 @@
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Test using_other_iterator_trait_methods" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<configuration name="Test lib::tests" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="test --package closures --lib using_other_iterator_trait_methods -- --exact" />
|
||||
<option name="command" value="test --package interior_mutability --lib tests" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/closures" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/interior_mutability" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="Test tests::it_sends_an_over_75_percent_warning_message" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="command" value="test --package interior_mutability --lib tests::it_sends_an_over_75_percent_warning_message -- --exact" />
|
||||
<option name="allFeatures" value="false" />
|
||||
<option name="nocapture" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$/interior_mutability" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
@ -272,10 +287,10 @@
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Cargo Command.Run reference_counting" />
|
||||
<item itemvalue="Cargo Command.Test lib::tests" />
|
||||
<item itemvalue="Cargo Command.Test tests::it_sends_an_over_75_percent_warning_message" />
|
||||
<item itemvalue="Cargo Command.Run smart_pointers" />
|
||||
<item itemvalue="Cargo Command.Test lib::tests (1)" />
|
||||
<item itemvalue="Cargo Command.Test using_other_iterator_trait_methods" />
|
||||
<item itemvalue="Cargo Command.Test calling_next_directly" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
@ -307,6 +322,9 @@
|
||||
<history-entry file="Test_using_other_iterator_trait_methods - 2019.02.01 at 16h 05m 11s.xml">
|
||||
<configuration name="Test using_other_iterator_trait_methods" configurationId="CargoCommandRunConfiguration" />
|
||||
</history-entry>
|
||||
<history-entry file="Test_lib__tests - 2019.02.05 at 10h 33m 57s.xml">
|
||||
<configuration name="Test lib::tests" configurationId="CargoCommandRunConfiguration" />
|
||||
</history-entry>
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="1680" y="-410" width="1050" height="1657" extended-state="6" />
|
||||
@ -329,7 +347,7 @@
|
||||
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
|
||||
<window_info anchor="bottom" id="Version Control" order="8" />
|
||||
<window_info anchor="bottom" id="Inspection Results" order="9" weight="0.32979318" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" weight="0.66429955" />
|
||||
<window_info anchor="bottom" id="Terminal" order="10" weight="0.3428018" />
|
||||
<window_info anchor="bottom" id="Event Log" order="11" side_tool="true" />
|
||||
<window_info anchor="right" id="Commander" order="0" weight="0.4" />
|
||||
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||
@ -731,10 +749,21 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/interior_mutability/src/lib.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="672">
|
||||
<caret line="55" column="69" selection-start-line="55" selection-start-column="69" selection-end-line="55" selection-end-column="69" />
|
||||
<folding>
|
||||
<element signature="e#1104#1105#0" expanded="true" />
|
||||
<element signature="e#1144#1145#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/reference_counting/src/main.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="224">
|
||||
<caret line="14" column="13" selection-start-line="14" selection-start-column="13" selection-end-line="14" selection-end-column="13" />
|
||||
<state relative-caret-position="320">
|
||||
<caret line="20" column="15" selection-start-line="20" selection-start-column="15" selection-end-line="20" selection-end-column="15" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
7
interior_mutability/Cargo.toml
Normal file
7
interior_mutability/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "interior_mutability"
|
||||
version = "0.1.0"
|
||||
authors = ["Timothy Warren <twarren@nabancard.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
70
interior_mutability/src/lib.rs
Normal file
70
interior_mutability/src/lib.rs
Normal file
@ -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<T> {
|
||||
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<Vec<String>>,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user