Add trait object example

This commit is contained in:
Timothy Warren 2019-02-06 14:28:09 -05:00
parent ec147dce21
commit bac5c02bd8
6 changed files with 187 additions and 85 deletions

View File

@ -32,6 +32,8 @@
<cargoProject FILE="$PROJECT_DIR$/mutex/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/oop/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/twelve_days_of_christmas/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/trait_objects/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/gui/Cargo.toml" />
</component>
<component name="ComposerJsonPluginSettings">
<unboundedVersionInspectionSettings>

View File

@ -130,6 +130,13 @@
<sourceFolder url="file://$MODULE_DIR$/twelve_days_of_christmas/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/twelve_days_of_christmas/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/twelve_days_of_christmas/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gui/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/trait_objects/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/trait_objects/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/trait_objects/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gui/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gui/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gui/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" />
@ -142,6 +149,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$/gui/target" />
<excludeFolder url="file://$MODULE_DIR$/interior_mutability/target" />
<excludeFolder url="file://$MODULE_DIR$/lifetimes/target" />
<excludeFolder url="file://$MODULE_DIR$/loops/target" />
@ -159,6 +167,7 @@
<excludeFolder url="file://$MODULE_DIR$/smart_pointers/target" />
<excludeFolder url="file://$MODULE_DIR$/structs/target" />
<excludeFolder url="file://$MODULE_DIR$/threads/target" />
<excludeFolder url="file://$MODULE_DIR$/trait_objects/target" />
<excludeFolder url="file://$MODULE_DIR$/twelve_days_of_christmas/target" />
<excludeFolder url="file://$MODULE_DIR$/variables/target" />
</content>

View File

@ -13,21 +13,7 @@
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileEditorManager">
<leaf>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/oop/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="784">
<caret line="49" column="29" selection-start-line="49" selection-start-column="29" selection-end-line="49" selection-end-column="29" />
<folding>
<element signature="e#510#511#0" expanded="true" />
<element signature="e#537#538#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
<leaf />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
@ -41,11 +27,13 @@
<find>ftoc</find>
<find>expensive_closure(intensity)</find>
<find>ordinals</find>
<find>///</find>
</findStrings>
<replaceStrings>
<replace>f_to_c</replace>
<replace>expensive_result.value(intensity)</replace>
<replace>ORDINALS</replace>
<replace>//!</replace>
</replaceStrings>
</component>
<component name="Git.Settings">
@ -54,11 +42,6 @@
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/functions/src/main.rs" />
<option value="$PROJECT_DIR$/branches/src/main.rs" />
<option value="$PROJECT_DIR$/ctof/src/main.rs" />
<option value="$PROJECT_DIR$/ftoc/src/main.rs" />
<option value="$PROJECT_DIR$/loops/src/main.rs" />
<option value="$PROJECT_DIR$/scope/src/main.rs" />
<option value="$PROJECT_DIR$/references/src/main.rs" />
<option value="$PROJECT_DIR$/slices/src/main.rs" />
@ -105,6 +88,11 @@
<option value="$PROJECT_DIR$/twelve_days_of_christmas/Cargo.toml" />
<option value="$PROJECT_DIR$/twelve_days_of_christmas/src/main.rs" />
<option value="$PROJECT_DIR$/oop/src/lib.rs" />
<option value="$PROJECT_DIR$/trait_objects/src/lib.rs" />
<option value="$PROJECT_DIR$/trait_objects/src/main.rs" />
<option value="$PROJECT_DIR$/trait_objects/Cargo.toml" />
<option value="$PROJECT_DIR$/gui/src/main.rs" />
<option value="$PROJECT_DIR$/gui/src/lib.rs" />
</list>
</option>
</component>
@ -135,6 +123,17 @@
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
</path>
<path>
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
<item name="twelve_days_of_christmas" type="9f88c78c:ScopeViewTreeModel$FileNode" />
</path>
<path>
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
<item name="twelve_days_of_christmas" type="9f88c78c:ScopeViewTreeModel$FileNode" />
<item name="src" type="9f88c78c:ScopeViewTreeModel$FileNode" />
</path>
</expand>
<select />
</subPane>
@ -166,7 +165,7 @@
</component>
<component name="PropertiesComponent">
<property name="JavaScriptWeakerCompletionTypeGuess" value="true" />
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549478828057" />
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549480480153" />
<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" />
@ -194,7 +193,7 @@
</list>
</option>
</component>
<component name="RunManager" selected="Cargo Command.Run twelve_days_of_christmas">
<component name="RunManager" selected="Cargo Command.Run gui">
<configuration name="&lt;template&gt;" type="TestNG" default="true" selected="false">
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" value="-ea" />
@ -213,6 +212,16 @@
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="Run gui" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package gui --bin gui" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/gui" />
<envs />
<method v="2" />
</configuration>
<configuration name="Run mutex" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package mutex --bin mutex" />
@ -223,26 +232,6 @@
<envs />
<method v="2" />
</configuration>
<configuration name="Run reference_counting" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package reference_counting --bin reference_counting" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/reference_counting" />
<envs />
<method v="2" />
</configuration>
<configuration name="Run reference_cycles" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package reference_cycles --bin reference_cycles" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/reference_cycles" />
<envs />
<method v="2" />
</configuration>
<configuration name="Run threads" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="run --package threads --bin threads" />
@ -263,6 +252,16 @@
<envs />
<method v="2" />
</configuration>
<configuration name="Test lib::tests" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package oop --lib tests" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/oop" />
<envs />
<method v="2" />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
@ -272,18 +271,15 @@
</configuration>
<recent_temporary>
<list>
<item itemvalue="Cargo Command.Run gui" />
<item itemvalue="Cargo Command.Test lib::tests" />
<item itemvalue="Cargo Command.Run twelve_days_of_christmas" />
<item itemvalue="Cargo Command.Run mutex" />
<item itemvalue="Cargo Command.Run threads" />
<item itemvalue="Cargo Command.Run reference_cycles" />
<item itemvalue="Cargo Command.Run reference_counting" />
</list>
</recent_temporary>
</component>
<component name="TestHistory">
<history-entry file="Test_tests__it_works - 2019.01.31 at 14h 06m 37s.xml">
<configuration name="Test tests::it_works" configurationId="CargoCommandRunConfiguration" />
</history-entry>
<history-entry file="Test_tests__greeting_contains_name - 2019.01.31 at 14h 18m 57s.xml">
<configuration name="Test tests::greeting_contains_name" configurationId="CargoCommandRunConfiguration" />
</history-entry>
@ -311,13 +307,15 @@
<history-entry file="Test_lib__tests - 2019.02.05 at 10h 33m 57s.xml">
<configuration name="Test lib::tests" configurationId="CargoCommandRunConfiguration" />
</history-entry>
<history-entry file="Test_lib__tests - 2019.02.06 at 13h 49m 17s.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" />
<editor active="true" />
<layout>
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.49644932" visible="true" weight="0.26141885" />
<window_info id="Structure" order="1" sideWeight="0.50355065" side_tool="true" visible="true" weight="0.26141885" />
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.4960707" visible="true" weight="0.26141885" />
<window_info id="Structure" order="1" sideWeight="0.50392926" side_tool="true" visible="true" weight="0.26141885" />
<window_info id="Image Layers" order="2" />
<window_info id="Designer" order="3" />
<window_info id="Capture Tool" order="4" />
@ -333,7 +331,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.3428018" />
<window_info anchor="bottom" id="Terminal" order="10" visible="true" 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" />
@ -347,31 +345,6 @@
<option name="version" value="1" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/branches/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="160">
<caret line="10" selection-start-line="10" selection-end-line="10" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/guessing_game/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="192">
<caret line="12" selection-start-line="12" selection-end-line="12" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ctof/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="304">
<caret line="19" column="8" selection-start-line="19" selection-start-column="8" selection-end-line="19" selection-end-column="8" />
<folding>
<element signature="e#450#451#0" expanded="true" />
<element signature="e#475#476#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ftoc/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="352">
@ -760,13 +733,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/twelve_days_of_christmas/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="112">
<caret line="7" column="27" lean-forward="true" selection-start-line="7" selection-start-column="27" selection-end-line="7" selection-end-column="27" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/twelve_days_of_christmas/Cargo.toml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="32">
@ -776,11 +742,45 @@
</entry>
<entry file="file://$PROJECT_DIR$/oop/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="784">
<caret line="49" column="29" selection-start-line="49" selection-start-column="29" selection-end-line="49" selection-end-column="29" />
<state relative-caret-position="720">
<caret line="45" lean-forward="true" selection-start-line="45" selection-end-line="45" />
<folding>
<element signature="e#510#511#0" expanded="true" />
<element signature="e#537#538#0" expanded="true" />
<element signature="e#956#957#0" expanded="true" />
<element signature="e#992#993#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/gui/Cargo.toml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="112">
<caret line="7" lean-forward="true" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/twelve_days_of_christmas/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="144">
<caret line="9" column="25" selection-start-line="9" selection-start-column="25" selection-end-line="9" selection-end-column="25" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/gui/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="576">
<caret line="36" lean-forward="true" selection-start-line="36" selection-end-line="36" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/gui/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="768">
<caret line="48" lean-forward="true" selection-start-line="48" selection-end-line="48" />
<folding>
<element signature="e#371#372#0" expanded="true" />
<element signature="e#407#408#0" expanded="true" />
</folding>
</state>
</provider>

7
gui/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "gui"
version = "0.1.0"
authors = ["Timothy Warren <twarren@nabancard.com>"]
edition = "2018"
[dependencies]

48
gui/src/lib.rs Normal file
View File

@ -0,0 +1,48 @@
//! An implementation of a "trait object",
//! which allows dynamic dispatch for implementing types,
//! even allowing disparate types to be called, unlike a
//! generic, which requires one specific implementation.
//!
//! Trait objects have some limitations (They must be "object-safe"):
//! * Methods can not return `Self`
//! * Methods can not have generic type parameters
/// The base trait definition
pub trait Draw {
fn draw(&self);
}
/// A struct able to utilize the "trait object", via the Box<dyn Draw> type
pub struct Screen {
pub components: Vec<Box<dyn Draw>>,
}
/// A method able to call the draw method on any objects
/// implementing the Draw "trait object"
impl Screen {
pub fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}
pub struct Button {
pub width: u32,
pub height: u32,
pub label: String,
}
impl Draw for Button {
fn draw(&self) {
// code to actually draw a button
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

36
gui/src/main.rs Normal file
View File

@ -0,0 +1,36 @@
use gui::{Button, Draw, Screen};
struct SelectBox {
width: u32,
height: u32,
options: Vec<String>,
}
impl Draw for SelectBox {
fn draw(&self) {
// code to actually draw a select box
}
}
fn main() {
let screen = Screen {
components: vec![
Box::new(SelectBox {
width: 75,
height: 10,
options: vec![
String::from("Yes"),
String::from("Maybe"),
String::from("No")
],
}),
Box::new(Button {
width: 50,
height: 10,
label: String::from("OK"),
}),
],
};
screen.run();
}