Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 564935689ab5527f955e5449ded02799 > files > 271

rust-doc-1.19.0-1.mga6.armv7hl.rpm

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Testing the Library's Functionality - The Rust Programming Language</title>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <base href="">

        <link rel="stylesheet" href="book.css">
        <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

        <link rel="shortcut icon" href="favicon.png">

        <!-- Font Awesome -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <style>
            .page-wrapper.has-warning > .nav-chapters {
              /* add height for warning content & margin */
              top: 120px;
            }

            p.warning {
                background-color: rgb(242, 222, 222);
                border-bottom-color: rgb(238, 211, 215);
                border-bottom-left-radius: 4px;
                border-bottom-right-radius: 4px;
                border-bottom-style: solid;
                border-bottom-width: 0.666667px;
                border-image-outset: 0 0 0 0;
                border-image-repeat: stretch stretch;
                border-image-slice: 100% 100% 100% 100%;
                border-image-source: none;
                border-image-width: 1 1 1 1;
                border-left-color: rgb(238, 211, 215);
                border-left-style: solid;
                border-left-width: 0.666667px;
                border-right-color: rgb(238, 211, 215);
                border-right-style: solid;
                border-right-width: 0.666667px;
                border-top-color: rgb(238, 211, 215);
                border-top-left-radius: 4px;
                border-top-right-radius: 4px;
                border-top-style: solid;
                border-top-width: 0.666667px;
                color: rgb(185, 74, 72);
                margin-bottom: 0px;
                margin-left: 0px;
                margin-right: 0px;
                margin-top: 30px;
                padding-bottom: 8px;
                padding-left: 14px;
                padding-right: 35px;
                padding-top: 8px;
            }
            p.warning strong {
                color: rgb(185, 74, 72)
            }
            p.warning a {
                color: rgb(0, 136, 204)
            }
        </style>

        <!-- MathJax -->
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

        <!-- Fetch JQuery from CDN but have a local fallback -->
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script>
            if (typeof jQuery == 'undefined') {
                document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
            }
        </script>
    </head>
    <body class="light">
        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme = localStorage.getItem('theme');
            if (theme == null) { theme = 'light'; }
            $('body').removeClass().addClass(theme);
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var sidebar = localStorage.getItem('sidebar');
            if (sidebar === "hidden") { $("html").addClass("sidebar-hidden") }
            else if (sidebar === "visible") { $("html").addClass("sidebar-visible") }
        </script>

        <div id="sidebar" class="sidebar">
            <ul class="chapter"><li><a href="ch01-00-introduction.html"><strong>1.</strong> Introduction</a></li><li><ul class="section"><li><a href="ch01-01-installation.html"><strong>1.1.</strong> Installation</a></li><li><a href="ch01-02-hello-world.html"><strong>1.2.</strong> Hello, World!</a></li></ul></li><li><a href="ch02-00-guessing-game-tutorial.html"><strong>2.</strong> Guessing Game Tutorial</a></li><li><a href="ch03-00-common-programming-concepts.html"><strong>3.</strong> Common Programming Concepts</a></li><li><ul class="section"><li><a href="ch03-01-variables-and-mutability.html"><strong>3.1.</strong> Variables and Mutability</a></li><li><a href="ch03-02-data-types.html"><strong>3.2.</strong> Data Types</a></li><li><a href="ch03-03-how-functions-work.html"><strong>3.3.</strong> How Functions Work</a></li><li><a href="ch03-04-comments.html"><strong>3.4.</strong> Comments</a></li><li><a href="ch03-05-control-flow.html"><strong>3.5.</strong> Control Flow</a></li></ul></li><li><a href="ch04-00-understanding-ownership.html"><strong>4.</strong> Understanding Ownership</a></li><li><ul class="section"><li><a href="ch04-01-what-is-ownership.html"><strong>4.1.</strong> What is Ownership?</a></li><li><a href="ch04-02-references-and-borrowing.html"><strong>4.2.</strong> References &amp; Borrowing</a></li><li><a href="ch04-03-slices.html"><strong>4.3.</strong> Slices</a></li></ul></li><li><a href="ch05-00-structs.html"><strong>5.</strong> Using Structs to Structure Related Data</a></li><li><ul class="section"><li><a href="ch05-01-defining-structs.html"><strong>5.1.</strong> Defining and Instantiating Structs</a></li><li><a href="ch05-02-example-structs.html"><strong>5.2.</strong> An Example Program Using Structs</a></li><li><a href="ch05-03-method-syntax.html"><strong>5.3.</strong> Method Syntax</a></li></ul></li><li><a href="ch06-00-enums.html"><strong>6.</strong> Enums and Pattern Matching</a></li><li><ul class="section"><li><a href="ch06-01-defining-an-enum.html"><strong>6.1.</strong> Defining an Enum</a></li><li><a href="ch06-02-match.html"><strong>6.2.</strong> The <code>match</code> Control Flow Operator</a></li><li><a href="ch06-03-if-let.html"><strong>6.3.</strong> Concise Control Flow with <code>if let</code></a></li></ul></li><li><a href="ch07-00-modules.html"><strong>7.</strong> Modules</a></li><li><ul class="section"><li><a href="ch07-01-mod-and-the-filesystem.html"><strong>7.1.</strong> <code>mod</code> and the Filesystem</a></li><li><a href="ch07-02-controlling-visibility-with-pub.html"><strong>7.2.</strong> Controlling Visibility with <code>pub</code></a></li><li><a href="ch07-03-importing-names-with-use.html"><strong>7.3.</strong> Importing Names with <code>use</code></a></li></ul></li><li><a href="ch08-00-common-collections.html"><strong>8.</strong> Common Collections</a></li><li><ul class="section"><li><a href="ch08-01-vectors.html"><strong>8.1.</strong> Vectors</a></li><li><a href="ch08-02-strings.html"><strong>8.2.</strong> Strings</a></li><li><a href="ch08-03-hash-maps.html"><strong>8.3.</strong> Hash Maps</a></li></ul></li><li><a href="ch09-00-error-handling.html"><strong>9.</strong> Error Handling</a></li><li><ul class="section"><li><a href="ch09-01-unrecoverable-errors-with-panic.html"><strong>9.1.</strong> Unrecoverable Errors with <code>panic!</code></a></li><li><a href="ch09-02-recoverable-errors-with-result.html"><strong>9.2.</strong> Recoverable Errors with <code>Result</code></a></li><li><a href="ch09-03-to-panic-or-not-to-panic.html"><strong>9.3.</strong> To <code>panic!</code> or Not To <code>panic!</code></a></li></ul></li><li><a href="ch10-00-generics.html"><strong>10.</strong> Generic Types, Traits, and Lifetimes</a></li><li><ul class="section"><li><a href="ch10-01-syntax.html"><strong>10.1.</strong> Generic Data Types</a></li><li><a href="ch10-02-traits.html"><strong>10.2.</strong> Traits: Defining Shared Behavior</a></li><li><a href="ch10-03-lifetime-syntax.html"><strong>10.3.</strong> Validating References with Lifetimes</a></li></ul></li><li><a href="ch11-00-testing.html"><strong>11.</strong> Testing</a></li><li><ul class="section"><li><a href="ch11-01-writing-tests.html"><strong>11.1.</strong> Writing tests</a></li><li><a href="ch11-02-running-tests.html"><strong>11.2.</strong> Running tests</a></li><li><a href="ch11-03-test-organization.html"><strong>11.3.</strong> Test Organization</a></li></ul></li><li><a href="ch12-00-an-io-project.html"><strong>12.</strong> An I/O Project</a></li><li><ul class="section"><li><a href="ch12-01-accepting-command-line-arguments.html"><strong>12.1.</strong> Accepting Command Line Arguments</a></li><li><a href="ch12-02-reading-a-file.html"><strong>12.2.</strong> Reading a File</a></li><li><a href="ch12-03-improving-error-handling-and-modularity.html"><strong>12.3.</strong> Improving Error Handling and Modularity</a></li><li><a href="ch12-04-testing-the-librarys-functionality.html" class="active"><strong>12.4.</strong> Testing the Library's Functionality</a></li><li><a href="ch12-05-working-with-environment-variables.html"><strong>12.5.</strong> Working with Environment Variables</a></li><li><a href="ch12-06-writing-to-stderr-instead-of-stdout.html"><strong>12.6.</strong> Writing to <code>stderr</code> instead of <code>stdout</code></a></li></ul></li><li><a href="ch13-00-functional-features.html"><strong>13.</strong> Functional Language Features in Rust</a></li><li><ul class="section"><li><a href="ch13-01-closures.html"><strong>13.1.</strong> Closures</a></li><li><a href="ch13-02-iterators.html"><strong>13.2.</strong> Iterators</a></li><li><a href="ch13-03-improving-our-io-project.html"><strong>13.3.</strong> Improving our I/O Project</a></li><li><a href="ch13-04-performance.html"><strong>13.4.</strong> Performance</a></li></ul></li><li><a href="ch14-00-more-about-cargo.html"><strong>14.</strong> More about Cargo and Crates.io</a></li><li><ul class="section"><li><a href="ch14-01-release-profiles.html"><strong>14.1.</strong> Release Profiles</a></li><li><a href="ch14-02-publishing-to-crates-io.html"><strong>14.2.</strong> Publishing a Crate to Crates.io</a></li><li><a href="ch14-03-cargo-workspaces.html"><strong>14.3.</strong> Cargo Workspaces</a></li><li><a href="ch14-04-installing-binaries.html"><strong>14.4.</strong> Installing Binaries from Crates.io with <code>cargo install</code></a></li><li><a href="ch14-05-extending-cargo.html"><strong>14.5.</strong> Extending Cargo with Custom Commands</a></li></ul></li><li><a href="ch15-00-smart-pointers.html"><strong>15.</strong> Smart Pointers</a></li><li><ul class="section"><li><a href="ch15-01-box.html"><strong>15.1.</strong> <code>Box&lt;T&gt;</code> Points to Data on the Heap and Has a Known Size</a></li><li><a href="ch15-02-deref.html"><strong>15.2.</strong> The <code>Deref</code> Trait Allows Access to the Data Through a Reference</a></li><li><a href="ch15-03-drop.html"><strong>15.3.</strong> The <code>Drop</code> Trait Runs Code on Cleanup</a></li><li><a href="ch15-04-rc.html"><strong>15.4.</strong> <code>Rc&lt;T&gt;</code>, the Reference Counted Smart Pointer</a></li><li><a href="ch15-05-interior-mutability.html"><strong>15.5.</strong> <code>RefCell&lt;T&gt;</code> and the Interior Mutability Pattern</a></li><li><a href="ch15-06-reference-cycles.html"><strong>15.6.</strong> Creating Reference Cycles and Leaking Memory is Safe</a></li></ul></li><li><a href="ch16-00-concurrency.html"><strong>16.</strong> Fearless Concurrency</a></li><li><ul class="section"><li><a href="ch16-01-threads.html"><strong>16.1.</strong> Threads</a></li><li><a href="ch16-02-message-passing.html"><strong>16.2.</strong> Message Passing</a></li><li><a href="ch16-03-shared-state.html"><strong>16.3.</strong> Shared State</a></li><li><a href="ch16-04-extensible-concurrency-sync-and-send.html"><strong>16.4.</strong> Extensible Concurrency: <code>Sync</code> and <code>Send</code></a></li></ul></li><li><a href="ch17-00-oop.html"><strong>17.</strong> Is Rust an Object-Oriented Programming Language?</a></li><li><ul class="section"><li><a href="ch17-01-what-is-oo.html"><strong>17.1.</strong> What Does Object-Oriented Mean?</a></li><li><a href="ch17-02-trait-objects.html"><strong>17.2.</strong> Trait Objects for Using Values of Different Types</a></li><li><a href="ch17-03-oo-design-patterns.html"><strong>17.3.</strong> Object-Oriented Design Pattern Implementations</a></li></ul></li><li><a href="ch18-00-patterns.html"><strong>18.</strong> Patterns Match the Structure of Values</a></li><li><ul class="section"><li><a href="ch18-01-all-the-places-for-patterns.html"><strong>18.1.</strong> All the Places Patterns May be Used</a></li><li><a href="ch18-02-refutability.html"><strong>18.2.</strong> Refutability: Whether a Pattern Might Fail to Match</a></li><li><a href="ch18-03-pattern-syntax.html"><strong>18.3.</strong> All the Pattern Syntax</a></li></ul></li><li><a href="ch19-00-advanced-features.html"><strong>19.</strong> Advanced Features</a></li><li><ul class="section"><li><a href="ch19-01-unsafe-rust.html"><strong>19.1.</strong> Unsafe Rust</a></li><li><a href="ch19-02-advanced-lifetimes.html"><strong>19.2.</strong> Advanced Lifetimes</a></li><li><a href="ch19-03-advanced-traits.html"><strong>19.3.</strong> Advanced Traits</a></li><li><a href="ch19-04-advanced-types.html"><strong>19.4.</strong> Advanced Types</a></li><li><a href="ch19-05-advanced-functions-and-closures.html"><strong>19.5.</strong> Advanced Functions &amp; Closures</a></li></ul></li><li><a href="ch20-00-final-project-a-web-server.html"><strong>20.</strong> Final Project: Building a Multithreaded Web Server</a></li><li><ul class="section"><li><a href="ch20-01-single-threaded.html"><strong>20.1.</strong> A Single Threaded Web Server</a></li><li><a href="ch20-02-slow-requests.html"><strong>20.2.</strong> How Slow Requests Affect Throughput</a></li><li><a href="ch20-03-designing-the-interface.html"><strong>20.3.</strong> Designing the Thread Pool Interface</a></li><li><a href="ch20-04-storing-threads.html"><strong>20.4.</strong> Creating the Thread Pool and Storing Threads</a></li><li><a href="ch20-05-sending-requests-via-channels.html"><strong>20.5.</strong> Sending Requests to Threads Via Channels</a></li><li><a href="ch20-06-graceful-shutdown-and-cleanup.html"><strong>20.6.</strong> Graceful Shutdown and Cleanup</a></li></ul></li><li><a href="appendix-00.html"><strong>21.</strong> Appendix</a></li><li><ul class="section"><li><a href="appendix-01-keywords.html"><strong>21.1.</strong> A - Keywords</a></li><li><a href="appendix-02-operators.html"><strong>21.2.</strong> B - Operators</a></li><li><strong>21.3.</strong> C - Derivable Traits</li><li><strong>21.4.</strong> D - Nightly Rust</li><li><strong>21.5.</strong> E - Macros</li><li><strong>21.6.</strong> F - Translations</li><li><a href="appendix-07-newest-features.html"><strong>21.7.</strong> G - Newest Features</a></li></ul></li></ul>
        </div>

        <div id="page-wrapper" class="page-wrapper has-warning">

            <div class="page">
                <header><p class="warning">You are reading a <strong>draft</strong> of the next edition of TRPL. For more, go <a href="../index.html">here</a>.</p></header>
                <div id="menu-bar" class="menu-bar">
                    <div class="left-buttons">
                        <i id="sidebar-toggle" class="fa fa-bars"></i>
                        <i id="theme-toggle" class="fa fa-paint-brush"></i>
                    </div>

                    <h1 class="menu-title">The Rust Programming Language</h1>

                    <div class="right-buttons">
                        <i id="print-button" class="fa fa-print" title="Print this book"></i>
                    </div>
                </div>


                <div id="content" class="content">
                    <a class="header" href="ch12-04-testing-the-librarys-functionality.html#testing-the-librarys-functionality" id="testing-the-librarys-functionality"><h2>Testing the Library's Functionality</h2></a>
<p>Now that we've extracted the logic into <em>src/lib.rs</em> and left all the argument
parsing and error handling in <em>src/main.rs</em>, it's much easier for us to write
tests for the core functionality of our code. We can call our functions
directly with various arguments and check return values without having to call
our binary from the command line.</p>
<p>In this section, we're going to follow the Test Driven Development (TDD)
process. This is a software development technique that follows this set of
steps:</p>
<ol>
<li>Write a test that fails, and run it to make sure it fails for the reason
you expected.</li>
<li>Write or modify just enough code to make the new test pass.</li>
<li>Refactor the code you just added or changed, and make sure the tests
continue to pass.</li>
<li>Repeat!</li>
</ol>
<p>This is just one of many ways to write software, but TDD can help drive the
design of code. Writing the test before writing the code that makes the test
pass helps to maintain high test coverage throughout the process.</p>
<p>We're going to test drive the implementation of the part of our <code>greprs</code>
program that will actually do the searching for the query string in the file
contents and produce a list of lines that match the query. We're going to add
this functionality in a function called <code>search</code>.</p>
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#writing-a-failing-test" id="writing-a-failing-test"><h3>Writing a Failing Test</h3></a>
<p>First, since we don't really need them any more, let's remove the <code>println!</code>
statements from both <em>src/lib.rs</em> and <em>src/main.rs</em>. Then we'll add a <code>test</code>
module with a test function, like we did in Chapter 11. The test function
specifies the behavior we'd like the <code>search</code> function to have: it will take
a query and the text to search for the query in, and will return only the lines
from the text that contain the query. Listing 12-15 shows this test:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# fn search&lt;'a&gt;(query: &amp;str, contents: &amp;'a str) -&gt; Vec&lt;&amp;'a str&gt; {
#      vec![]
# }
#
#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn one_result() {
        let query = &quot;duct&quot;;
        let contents = &quot;\
Rust:
safe, fast, productive.
Pick three.&quot;;

        assert_eq!(
            vec![&quot;safe, fast, productive.&quot;],
            search(query, contents)
        );
    }
}

#}</code></pre></pre>
<p><span class="caption">Listing 12-15: Creating a failing test for the <code>search</code>
function we wish we had</span></p>
<p>We've chosen to use &quot;duct&quot; as the string we're looking for in this test. The
text we're searching in is three lines, only one of which contains &quot;duct&quot;. We
assert that the value returned from the <code>search</code> function contains only the one
line we expect.</p>
<p>We aren't able to run this test and watch it fail though, since this test
doesn't even compile yet! We're going to add just enough code to get it to
compile: a definition of the <code>search</code> function that always returns an empty
vector, as shown in Listing 12-16. Once we have this, the test should compile
and fail because an empty vector doesn't match a vector containing the one
line <code>&quot;safe, fast, productive.&quot;</code>.</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
fn search&lt;'a&gt;(query: &amp;str, contents: &amp;'a str) -&gt; Vec&lt;&amp;'a str&gt; {
     vec![]
}

#}</code></pre></pre>
<p><span class="caption">Listing 12-16: Defining just enough of the <code>search</code>
function that our test will compile</span></p>
<!-- Will add ghosting and wingdings in libreoffice /Carol -->
<p>Notice that we need an explicit lifetime <code>'a</code> defined in the signature of
<code>search</code> and used with the <code>contents</code> argument and the return value. Remember
from Chapter 10 that the lifetime parameters specify which argument lifetime is
connected to the lifetime of the return value. In this case, we're indicating
that the returned vector should contain string slices that reference slices of
the argument <code>contents</code> (rather than the argument <code>query</code>).</p>
<p>In other words, we're telling Rust that the data returned by the <code>search</code>
function will live as long as the data passed into the <code>search</code> function in the
<code>contents</code> argument. This is important! The data referenced <em>by</em> a slice needs
to be valid in order for the reference to be valid; if the compiler assumed we
were making string slices of <code>query</code> rather than <code>contents</code>, it would do its
safety checking incorrectly.</p>
<p>If we tried to compile this function without lifetimes, we would get this error:</p>
<pre><code class="language-text">error[E0106]: missing lifetime specifier
 --&gt; src/lib.rs:5:47
  |
5 | fn search(query: &amp;str, contents: &amp;str) -&gt; Vec&lt;&amp;str&gt; {
  |                                               ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the
  signature does not say whether it is borrowed from `query` or `contents`
</code></pre>
<p>Rust can't possibly know which of the two arguments we need, so we need to tell
it. Because <code>contents</code> is the argument that contains all of our text and we
want to return the parts of that text that match, we know <code>contents</code> is the
argument that should be connected to the return value using the lifetime syntax.</p>
<p>Other programming languages don't require you to connect arguments to return
values in the signature, so this may still feel strange, but will get easier
over time. You may want to compare this example with the Lifetime Syntax
section in Chapter 10.</p>
<p>Now let's try running our test:</p>
<pre><code class="language-text">$ cargo test
...warnings...
    Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs
     Running target/debug/deps/greprs-abcabcabc

running 1 test
test test::one_result ... FAILED

failures:

---- test::one_result stdout ----
    thread 'test::one_result' panicked at 'assertion failed: `(left == right)`
(left: `[&quot;safe, fast, productive.&quot;]`, right: `[]`)', src/lib.rs:16
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    test::one_result

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

error: test failed
</code></pre>
<p>Great, our test fails, exactly as we expected. Let's get the test to pass!</p>
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#writing-code-that-gets-the-test-to-pass" id="writing-code-that-gets-the-test-to-pass"><h3>Writing Code that Gets the Test to Pass</h3></a>
<p>Currently, our test is failing because we always return an empty vector. To fix
that and implement <code>search</code>, our program needs to follow these steps:</p>
<ol>
<li>Iterate through each line of the contents.</li>
<li>Check if the line contains our query string.
<ul>
<li>If it does, add it to the list of values we're returning.</li>
<li>If it doesn't, do nothing.</li>
</ul>
</li>
<li>Return the list of results that match.</li>
</ol>
<p>Let's take each step at a time, starting with iterating through lines.</p>
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#iterating-through-lines-with-the-lines-method" id="iterating-through-lines-with-the-lines-method"><h4>Iterating Through Lines with the <code>lines</code> method</h4></a>
<p>Rust has a helpful method to handle line-by-line iteration of strings,
conveniently named <code>lines</code>, that works as shown in Listing 12-17:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><code class="language-rust ignore">fn search&lt;'a&gt;(query: &amp;str, contents: &amp;'a str) -&gt; Vec&lt;&amp;'a str&gt; {
    for line in contents.lines() {
        // do something with line
    }
}
</code></pre>
<p><span class="caption">Listing 12-17: Iterating through each line in
<code>contents</code></span></p>
<!-- Will add wingdings in libreoffice /Carol -->
<p>The <code>lines</code> method returns an iterator. We'll be talking about iterators in
depth in Chapter 13, but we've already seen this way of using an iterator in
Listing 3-6, where we used a <code>for</code> loop with an iterator to run some code on
each item in a collection.</p>
<!-- so what does `lines` do on its own, if we need to use it in a for loop to
work? -->
<!-- It does nothing on its own, it returns an iterator for you to do something
with. Here, the thing we're doing with it is using it with a `for` loop. I'm
not sure exactly what you're asking or how to make the text clearer, but I
added a reference to where we've done this in the book previously. /Carol -->
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#searching-each-line-for-the-query" id="searching-each-line-for-the-query"><h4>Searching Each Line for the Query</h4></a>
<p>Next, we'll add functionality to check if the current line contains the query
string. Luckily, strings have another helpful method named <code>contains</code> that does
this for us! Add the <code>contains</code> method to the <code>search</code> function as shown in
Listing 12-18:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><code class="language-rust ignore">fn search&lt;'a&gt;(query: &amp;str, contents: &amp;'a str) -&gt; Vec&lt;&amp;'a str&gt; {
    for line in contents.lines() {
        if line.contains(query) {
            // do something with line
        }
    }
}
</code></pre>
<p><span class="caption">Listing 12-18: Adding functionality to see if the line
contains the string in <code>query</code></span></p>
<!-- Will add ghosting and wingdings in libreoffice /Carol -->
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#storing-matching-lines" id="storing-matching-lines"><h4>Storing Matching Lines</h4></a>
<p>Finally, we need a way to store the lines that contain our query string. For
that, we can make a mutable vector before the <code>for</code> loop and call the <code>push</code>
method to store a <code>line</code> in the vector. After the <code>for</code> loop, we return the
vector, as shown in Listing 12-19:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><code class="language-rust ignore">fn search&lt;'a&gt;(query: &amp;str, contents: &amp;'a str) -&gt; Vec&lt;&amp;'a str&gt; {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }

    results
}
</code></pre>
<p><span class="caption">Listing 12-19: Storing the lines that match so that we
can return them</span></p>
<!-- Will add ghosting and wingdings in libreoffice /Carol -->
<p>Now the <code>search</code> function should be returning only the lines that contain
<code>query</code>, and our test should pass. Let's run the tests:</p>
<pre><code class="language-text">$ cargo test
running 1 test
test test::one_result ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

     Running target/debug/greprs-2f55ee8cd1721808

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests greprs

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
</code></pre>
<p>Our test passed, great, it works!</p>
<p>Now that our test is passing, we could consider opportunities for refactoring
the implementation of the <code>search</code> function while keeping the tests passing in
order to maintain the same functionality while we do so. This code isn't bad,
but it isn't taking advantage of some useful features of iterators. We'll be
coming back to this example in Chapter 13 where we'll explore iterators in
detail and see how to improve it.</p>
<!-- If we aren't going into this here, maybe just keep it focused, there's a
lot going on here as is -->
<!-- The reason we mention refactoring here is that it's a key step in the TDD
method that we were implicitly using before. Now that we've added text to the
beginning of this section to explicitly mention that we're doing TDD and what
the steps are, we want to address the "refactor" step. People who have some
experience with Rust might also look at this example and wonder why we're not
doing this in a different way, and be concerned that we're not teaching the
best way possible. This paragraph reassures them that we know what we're doing
and we're getting to the better way in Chapter 13. /Carol -->
<a class="header" href="ch12-04-testing-the-librarys-functionality.html#using-the-search-function-in-the-run-function" id="using-the-search-function-in-the-run-function"><h4>Using the <code>search</code> Function in the <code>run</code> Function</h4></a>
<p>Now that we have the <code>search</code> function working and tested, we need to actually
call <code>search</code> from our <code>run</code> function. We need to pass the <code>config.query</code> value
and the <code>contents</code> that <code>run</code> read from the file to the <code>search</code> function. Then
<code>run</code> will print out each line returned from <code>search</code>:</p>
<p><span class="filename">Filename: src/lib.rs</span></p>
<pre><code class="language-rust ignore">pub fn run(config: Config) -&gt; Result&lt;(), Box&lt;Error&gt;&gt; {
    let mut f = File::open(config.filename)?;

    let mut contents = String::new();
    f.read_to_string(&amp;mut contents)?;

    for line in search(&amp;config.query, &amp;contents) {
        println!(&quot;{}&quot;, line);
    }

    Ok(())
}
</code></pre>
<!-- Will add ghosting and wingdings in libreoffice /Carol -->
<p>We're again using a <code>for</code> loop to get each line returned from <code>search</code>, and
the code that we run for each line prints it out.</p>
<p>Now our whole program should be working! Let's try it out, first with a word
that should return exactly one line from the Emily Dickinson poem, &quot;frog&quot;:</p>
<pre><code class="language-text">$ cargo run frog poem.txt
   Compiling greprs v0.1.0 (file:///projects/greprs)
    Finished dev [unoptimized + debuginfo] target(s) in 0.38 secs
     Running `target/debug/greprs frog poem.txt`
How public, like a frog
</code></pre>
<p>Cool! Next, how about a word that will match multiple lines, like &quot;the&quot;:</p>
<pre><code class="language-text">$ cargo run the poem.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/greprs the poem.txt`
Then there's a pair of us — don't tell!
To tell your name the livelong day
</code></pre>
<p>And finally, let's make sure that we don't get any lines when we search for a
word that isn't anywhere in the poem, like &quot;monomorphization&quot;:</p>
<pre><code class="language-text">$ cargo run monomorphization poem.txt
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/greprs monomorphization poem.txt`
</code></pre>
<p>Excellent! We've built our own version of a classic tool, and learned a lot
about how to structure applications. We've also learned a bit about file input
and output, lifetimes, testing, and command line parsing.</p>
<p>Feel free to move on to Chapter 13 if you'd like at this point. To round out
this project chapter, though, we're going to briefly demonstrate how to work
with environment variables and printing to standard error, both of which are
useful when writing command line programs.</p>

                </div>

                <!-- Mobile navigation buttons -->
                
                    <a href="ch12-03-improving-error-handling-and-modularity.html" class="mobile-nav-chapters previous">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
                    <a href="ch12-05-working-with-environment-variables.html" class="mobile-nav-chapters next">
                        <i class="fa fa-angle-right"></i>
                    </a>
                

            </div>

            
                <a href="ch12-03-improving-error-handling-and-modularity.html" class="nav-chapters previous" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-left"></i>
                </a>
            

            
                <a href="ch12-05-working-with-environment-variables.html" class="nav-chapters next" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-right"></i>
                </a>
            

        </div>


        <!-- Local fallback for Font Awesome -->
        <script>
            if ($(".fa").css("font-family") !== "FontAwesome") {
                $('<link rel="stylesheet" type="text/css" href="_FontAwesome/css/font-awesome.css">').prependTo('head');
            }
        </script>

        <!-- Livereload script (if served using the cli tool) -->
        

        <script src="highlight.js"></script>
        <script src="book.js"></script>
    </body>
</html>