rust-cli / book

Documentation on how to use the Rust Programming Language to develop commandline applications
https://rust-cli.github.io/book/index.html
MIT License
816 stars 108 forks source link

Book section 1.6 testing does not work #227

Closed acgetchell closed 11 months ago

acgetchell commented 1 year ago

This snippet:

fn main() -> Result<()> {
    let args = Cli::parse();
    let content = std::fs::read_to_string(&args.path)
        .with_context(|| format!("could not read file `{}`", args.path.display()))?;

    find_matches(&content, &args.pattern, &mut std::io::stdout());

    Ok(())
}

Produces the following:

$ cargo run Compiling grrs v0.1.0 (/Users/adam/projects/grrs) error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied --> src/main.rs:23:14 23 fn main() -> Result<()> { ^^^^^^ -- supplied 1 generic argument
expected 2 generic arguments
note: enum defined here, with 2 generic parameters: T, E --> /Users/adam/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:502:10 502 pub enum Result<T, E> { ^^^^^^ - - help: add missing generic argument
23 fn main() -> Result<(), E> {
+++
acgetchell commented 1 year ago

This works:

#![allow(unused)]

use anyhow::Context;
use clap::Parser;
use std::error::Error;

pub type Result<T, E = dyn Error> = std::result::Result<T, E>;

/// Search for a pattern in a file and display the lines that contain it.
#[derive(Parser)]
struct Cli {
    /// The pattern to look for
    pattern: String,
    /// The path to the file to read
    path: std::path::PathBuf,
}

fn find_matches(content: &str, pattern: &str, mut writer: impl std::io::Write) {
    for line in content.lines() {
        if line.contains(pattern) {
            writeln!(writer, "{}", line);
        }
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let args = Cli::parse();
    let content = std::fs::read_to_string(&args.path)
        .with_context(|| format!("could not read file `{}`", args.path.display()))?;

    find_matches(&content, &args.pattern, &mut std::io::stdout());

    Ok(())
}

#[test]
fn find_a_match() {
    let mut result = Vec::new();
    find_matches("lorem ipsum\ndolor sit amet", "lorem", &mut result);
    assert_eq!(result, b"lorem ipsum\n");
}
epage commented 11 months ago

The file is at https://github.com/rust-cli/book/blob/master/src/tutorial/testing/src/main.rs and is tested.

The important bit is:

Here’s an example of a main function that builds on what we’ve seen in the previous chapters and uses our extracted find_matches function

For what its referring to, see this main.