Crate cradle[][src]

Expand description

(cradle is in an early stage of development. APIs may change drastically! Use at your own risk!)

cradle provides the cmd! macro, that makes it easy to run child processes from rust programs.

use cradle::*;

let StdoutTrimmed(stdout) = cmd!(%"echo foo");
assert_eq!(stdout, "foo");

Arguments

You can pass in multiple arguments (of different types) to cmd! to specify arguments, as long as they implement the CmdArgument trait:

use cradle::*;

let StdoutTrimmed(stdout) = cmd!("echo", "foo", "bar");
assert_eq!(stdout, "foo bar");

For all possible inputs to cmd!, see the documentation of CmdArgument.

Whitespace Splitting

cradle does not split given string arguments on whitespace by default. So for example this code fails:

use cradle::*;

let StdoutTrimmed(_) = cmd!("echo foo");

In this code cradle tries to run a process from an executable called "echo foo", including the space in the file name of the executable. That fails, because an executable with that name doesn’t exist. cradle provides a new-type wrapper Split to help with that:

use cradle::*;

let StdoutTrimmed(output) = cmd!(Split("echo foo"));
assert_eq!(output, "foo");

Wrapping an argument of type &str in Split will cause cradle to first split it by whitespace and then use the resulting words as if they were passed into cmd! as separate arguments.

And – since this is such a common case – cradle provides a syntactic shortcut for Split, the % symbol:

use cradle::*;

let StdoutTrimmed(output) = cmd!(%"echo foo");
assert_eq!(output, "foo");

Output

You can choose which return type you want cmd! to return, as long as the chosen return type implements CmdOutput. For example you can use e.g. StdoutTrimmed to collect what the child process writes to stdout, trimmed of leading and trailing whitespace:

use cradle::*;

let StdoutTrimmed(output) = cmd!(%"echo foo");
assert_eq!(output, "foo");

(By default, the child’s stdout is written to the parent’s stdout. Using StdoutTrimmed as the return type suppresses that.)

If you don’t want any result from cmd!, you can use () as the return value:

use cradle::*;

let () = cmd!(%"touch foo");

Since that’s a very common case, cradle provides the cmd_unit! shortcut, that behaves exactly like cmd!, but pins the return type down to ():

use cradle::*;

cmd_unit!(%"touch foo");

See the implementations for CmdOutput for all the supported types.

Error Handling

By default cmd! panics for a few reasons, e.g.:

  • when the child process exits with a non-zero exitcode,
  • when the given executable cannot be found,
  • when no strings are given as arguments to cmd!.

For example:

use cradle::*;

// panics with "false:\n  exited with exit code: 1"
cmd_unit!("false");

You can suppress panics caused by non-zero exit codes by using the Exit type as a return type of cmd!:

use cradle::*;

let Exit(exit_status) = cmd!("false");
assert_eq!(exit_status.code(), Some(1));

You can also turn all panics into std::result::Result::Errs by using cmd_result!. This will return a value of type Result<T, cradle::Error>, where T is any type that implements CmdOutput. Here’s some examples:

use cradle::*;

let result: Result<(), cradle::Error> = cmd_result!("false");
let error_message = format!("{}", result.unwrap_err());
assert_eq!(
    error_message,
    "false:\n  exited with exit code: 1"
);

let result = cmd_result!(%"echo foo");
let StdoutTrimmed(output) = result.unwrap();
assert_eq!(output, "foo".to_string());

cmd_result can also be combined with ? to handle errors in an idiomatic way, for example:

use cradle::*;

fn build() -> Result<(), Error> {
    cmd_result!(%"which make")?;
    cmd_result!(%"which gcc")?;
    cmd_result!(%"which ld")?;
    cmd_result!(%"make build")?;
    Ok(())
}

Prior Art

cradle is heavily inspired by shake, specifically by its cmd function.

Macros

cmd

Execute child processes. See the module documentation on how to use it.

cmd_result

Like cmd!, but fixes the return type to Result<T, Error>, where T is any type that implements CmdOutput.

cmd_unit

Like cmd!, but fixes the return type to ().

Structs

CurrentDir

See the CmdArgument implementation for CurrentDir below.

Exit

See the CmdOutput implementation for Exit below.

LogCommand

See the CmdArgument implementation for LogCommand below.

Split

See the CmdArgument implementation for Split below.

Stderr

See the CmdOutput implementation for Stderr below.

StdoutTrimmed

See the CmdOutput implementation for StdoutTrimmed below.

StdoutUntrimmed

See the CmdOutput implementation for StdoutUntrimmed below.

Enums

Error

Traits

CmdArgument

All types that are possible arguments to cmd! have to implement this trait.

CmdOutput

All possible return types of cmd! have to implement this trait. For documentation about what these return types do, see the individual implementations below.