Add iterator/closure updated version of minigrep example

This commit is contained in:
Timothy Warren 2019-02-01 16:33:01 -05:00
parent d4835dc6b8
commit b10c01f40c
6 changed files with 198 additions and 22 deletions

1
.idea/misc.xml generated
View File

@ -22,6 +22,7 @@
<cargoProject FILE="$PROJECT_DIR$/adder/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/minigrep/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/closures/Cargo.toml" />
<cargoProject FILE="$PROJECT_DIR$/minigrep_v2/Cargo.toml" />
</component>
<component name="ComposerJsonPluginSettings">
<unboundedVersionInspectionSettings>

5
.idea/rust.iml generated
View File

@ -86,6 +86,10 @@
<sourceFolder url="file://$MODULE_DIR$/closures/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/closures/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/closures/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/minigrep_v2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/minigrep_v2/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/minigrep_v2/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/minigrep_v2/benches" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/adder/target" />
<excludeFolder url="file://$MODULE_DIR$/branches/target" />
<excludeFolder url="file://$MODULE_DIR$/closures/target" />
@ -99,6 +103,7 @@
<excludeFolder url="file://$MODULE_DIR$/lifetimes/target" />
<excludeFolder url="file://$MODULE_DIR$/loops/target" />
<excludeFolder url="file://$MODULE_DIR$/minigrep/target" />
<excludeFolder url="file://$MODULE_DIR$/minigrep_v2/target" />
<excludeFolder url="file://$MODULE_DIR$/modules/target" />
<excludeFolder url="file://$MODULE_DIR$/rectangles/target" />
<excludeFolder url="file://$MODULE_DIR$/references/target" />

91
.idea/workspace.xml generated
View File

@ -2,6 +2,8 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="c8f42924-1cd2-4b1c-bcff-602a3368bb16" name="Default Changelist" comment="">
<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" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
@ -12,15 +14,29 @@
</component>
<component name="FileEditorManager">
<leaf>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/closures/src/lib.rs">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/minigrep_v2/Cargo.toml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1165">
<caret line="74" column="1" selection-start-line="74" selection-start-column="1" selection-end-line="74" selection-end-column="1" />
<folding>
<element signature="e#437#438#0" expanded="true" />
<element signature="e#472#473#0" expanded="true" />
</folding>
<state relative-caret-position="112">
<caret line="7" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/minigrep_v2/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="17" lean-forward="true" selection-start-line="17" selection-end-line="17" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/minigrep_v2/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="960">
<caret line="60" column="40" selection-start-line="60" selection-start-column="40" selection-end-line="60" selection-end-column="40" />
</state>
</provider>
</entry>
@ -85,6 +101,8 @@
<option value="$PROJECT_DIR$/minigrep/src/main.rs" />
<option value="$PROJECT_DIR$/closures/src/main.rs" />
<option value="$PROJECT_DIR$/closures/src/lib.rs" />
<option value="$PROJECT_DIR$/minigrep_v2/src/main.rs" />
<option value="$PROJECT_DIR$/minigrep_v2/src/lib.rs" />
</list>
</option>
</component>
@ -118,12 +136,17 @@
<path>
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
<item name="closures" type="9f88c78c:ScopeViewTreeModel$FileNode" />
<item name="minigrep" type="9f88c78c:ScopeViewTreeModel$FileNode" />
</path>
<path>
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
<item name="closures" type="9f88c78c:ScopeViewTreeModel$FileNode" />
<item name="minigrep_v2" type="9f88c78c:ScopeViewTreeModel$FileNode" />
</path>
<path>
<item name="rust" type="3d21c010:ScopeViewTreeModel$ProjectNode" />
<item name="rust" type="2674bda8:ScopeViewTreeModel$GroupNode" />
<item name="minigrep_v2" type="9f88c78c:ScopeViewTreeModel$FileNode" />
<item name="src" type="9f88c78c:ScopeViewTreeModel$FileNode" />
</path>
</expand>
@ -157,7 +180,7 @@
</component>
<component name="PropertiesComponent">
<property name="JavaScriptWeakerCompletionTypeGuess" value="true" />
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549055111185" />
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1549056665919" />
<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" />
@ -185,7 +208,7 @@
</list>
</option>
</component>
<component name="RunManager" selected="Cargo Command.Test using_other_iterator_trait_methods">
<component name="RunManager" selected="Cargo Command.Test lib::tests (1)">
<configuration name="&lt;template&gt;" type="TestNG" default="true" selected="false">
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" value="-ea" />
@ -234,13 +257,13 @@
<envs />
<method v="2" />
</configuration>
<configuration name="Test lib::tests" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<configuration name="Test lib::tests (1)" type="CargoCommandRunConfiguration" factoryName="Cargo Command" temporary="true">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package adder --lib tests" />
<option name="command" value="test --package minigrep_v2 --lib tests" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/adder" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/minigrep_v2" />
<envs />
<method v="2" />
</configuration>
@ -263,11 +286,11 @@
</configuration>
<recent_temporary>
<list>
<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" />
<item itemvalue="Cargo Command.Test filters_by_size" />
<item itemvalue="Cargo Command.Run closures" />
<item itemvalue="Cargo Command.Test lib::tests" />
</list>
</recent_temporary>
</component>
@ -296,13 +319,16 @@
<history-entry file="Test_calling_next_directly - 2019.02.01 at 16h 04m 05s.xml">
<configuration name="Test calling_next_directly" configurationId="CargoCommandRunConfiguration" />
</history-entry>
<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>
</component>
<component name="ToolWindowManager">
<frame x="1920" y="-438" width="1080" height="1897" extended-state="6" />
<editor active="true" />
<layout>
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.49642006" visible="true" weight="0.2540132" />
<window_info id="Structure" order="1" sideWeight="0.50358" side_tool="true" visible="true" weight="0.2540132" />
<window_info content_ui="combo" id="Project" order="0" sideWeight="0.4968701" visible="true" weight="0.2540132" />
<window_info id="Structure" order="1" sideWeight="0.5031299" side_tool="true" visible="true" weight="0.2540132" />
<window_info id="Image Layers" order="2" />
<window_info id="Designer" order="3" />
<window_info id="Capture Tool" order="4" />
@ -310,7 +336,7 @@
<window_info id="Cargo" order="6" sideWeight="0.49791494" weight="0.3286119" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" weight="0.32979318" />
<window_info active="true" anchor="bottom" id="Run" order="2" visible="true" weight="0.29737285" />
<window_info anchor="bottom" id="Run" order="2" weight="0.29737285" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
@ -318,7 +344,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.28563443" />
<window_info active="true" anchor="bottom" id="Terminal" order="10" visible="true" weight="0.28563443" />
<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" />
@ -630,8 +656,8 @@
</entry>
<entry file="file://$PROJECT_DIR$/closures/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1165">
<caret line="74" column="1" selection-start-line="74" selection-start-column="1" selection-end-line="74" selection-end-column="1" />
<state relative-caret-position="624">
<caret line="39" column="57" selection-start-line="39" selection-start-column="57" selection-end-line="39" selection-end-column="57" />
<folding>
<element signature="e#437#438#0" expanded="true" />
<element signature="e#472#473#0" expanded="true" />
@ -639,5 +665,26 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/minigrep_v2/Cargo.toml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="112">
<caret line="7" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/minigrep_v2/src/main.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="272">
<caret line="17" lean-forward="true" selection-start-line="17" selection-end-line="17" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/minigrep_v2/src/lib.rs">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="960">
<caret line="60" column="40" selection-start-line="60" selection-start-column="40" selection-end-line="60" selection-end-column="40" />
</state>
</provider>
</entry>
</component>
</project>

7
minigrep_v2/Cargo.toml Normal file
View File

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

99
minigrep_v2/src/lib.rs Normal file
View File

@ -0,0 +1,99 @@
use std::env;
use std::error::Error;
use std::fs;
pub struct Config {
pub query: String,
pub filename: String,
pub case_sensitive: bool,
}
impl Config {
pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
args.next(); // Skip the program's name
let query = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a query string"),
};
let filename = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a file name"),
};
let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
Ok(Config { query, filename, case_sensitive })
}
}
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
// The ? operator passes the error back to the caller.
let contents = fs::read_to_string(config.filename)?;
let results = if config.case_sensitive {
search(&config.query, &contents)
} else {
search_case_insensitive(&config.query, &contents)
};
for line in results {
println!("{}", line);
}
Ok(())
}
fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents.lines()
.filter(|line| line.contains(query))
.collect()
}
fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let query = query.to_lowercase();
contents.lines()
.filter(|line| {
line.to_lowercase()
.as_str()
.contains(query.as_str())
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn case_sensitive() {
let query = "duct";
let contents = "\
Rust:
safe, fast, productive.
Pick three.
Duct tape.";
assert_eq!(
vec!["safe, fast, productive."],
search(query, contents)
);
}
#[test]
fn case_insensitive() {
let query = "rUsT";
let contents = "\
Rust:
safe, fast, productive.
Pick three.
Trust me.";
assert_eq!(
vec!["Rust:", "Trust me."],
search_case_insensitive(query, contents)
);
}
}

17
minigrep_v2/src/main.rs Normal file
View File

@ -0,0 +1,17 @@
use std::env;
use std::process;
use minigrep_v2;
use minigrep_v2::Config;
fn main() {
let config = Config::new(env::args()).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {}", err);
process::exit(1);
});
if let Err(e) = minigrep_v2::run(config) {
eprintln!("Application error: {}", e);
process::exit(1);
}
}