1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::core::{Target, Workspace};
use crate::ops::CompileOptions;
use crate::util::CargoResult;

use std::fmt::Write;

fn get_available_targets<'a>(
    filter_fn: fn(&Target) -> bool,
    ws: &'a Workspace<'_>,
    options: &'a CompileOptions<'_>,
) -> CargoResult<Vec<&'a Target>> {
    let packages = options.spec.get_packages(ws)?;

    let mut targets: Vec<_> = packages
        .into_iter()
        .flat_map(|pkg| {
            pkg.manifest()
                .targets()
                .iter()
                .filter(|target| filter_fn(target))
        })
        .collect();

    targets.sort();

    Ok(targets)
}

fn print_available(
    filter_fn: fn(&Target) -> bool,
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
    option_name: &str,
    plural_name: &str,
) -> CargoResult<()> {
    let targets = get_available_targets(filter_fn, ws, options)?;

    let mut output = String::new();
    writeln!(output, "\"{}\" takes one argument.", option_name)?;

    if targets.is_empty() {
        writeln!(output, "No {} available.", plural_name)?;
    } else {
        writeln!(output, "Available {}:", plural_name)?;
        for target in targets {
            writeln!(output, "    {}", target.name())?;
        }
    }
    Err(failure::err_msg(output))
}

pub fn print_available_examples(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_example, ws, options, "--example", "examples")
}

pub fn print_available_binaries(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bin, ws, options, "--bin", "binaries")
}

pub fn print_available_benches(
    ws: &Workspace<'_>,
    options: &CompileOptions<'_>,
) -> CargoResult<()> {
    print_available(Target::is_bench, ws, options, "--bench", "benches")
}

pub fn print_available_tests(ws: &Workspace<'_>, options: &CompileOptions<'_>) -> CargoResult<()> {
    print_available(Target::is_test, ws, options, "--test", "tests")
}