[−][src]Crate shellfn
Overview
This is a rust attribute-like proc macro which reduces the amount of code required to call shell commands and parse the results.
It allows you to wrap a script in any language with strongly typed functions. The function's arguments are set as env variables and the result of the script is parsed either as a value or as an iterator.
Examples
Basic
use shellfn::shell; use std::error::Error; #[shell] fn list_modified(dir: &str) -> Result<impl Iterator<Item=String>, Box<Error>> { r#" cd $DIR git status | grep '^\s*modified:' | awk '{print $2}' "# }
Different interpreter
use shellfn::shell; use std::error::Error; #[shell(cmd = "python -c")] fn pretty_json(json: &str, indent: u8, sort_keys: bool) -> Result<String, Box<Error>> { r#" import os, json input = os.environ['JSON'] indent = int(os.environ['INDENT']) sort_keys = os.environ['SORT_KEYS'] == 'true' obj = json.loads(input) print(json.dumps(obj, indent=indent, sort_keys=sort_keys)) "# }
Usage
You can use the #[shell]
attribute on functions that have:
- a body containing only one expression - a string literal representing the script to execute
- types that implement the
.to_string()
method - return a value that is either
void
,T
,Result<T, E>
,impl Iterator<Item=T>
,Result<impl Iterator<Item=T>>
orResult<impl Iterator<Item=Result<T, E>>>
with constrains:
T: FromStr, <T as FromStr>::Err: StdError, E: From<shellfn::Error<<T as FromStr>::Err>>,
The #[shell]
attribute does the following:
- Sets every argument as an env variable
- Runs a shell command
- Launches the command using
std::process::Command
- Depending on the return type, it may parse the output
Most of the steps can be adjusted:
- the default command is
bash -c
. You can change it using thecmd
parameter:
#[shell(cmd = "python -c")]
- by default, the script is added as the last argument. You can change it using the special variable
PROGRAM
in thecmd
parameter:
#[shell(cmd = "bash -c PROGRAM -i")]
- if the return type is not wrapping some part of the result in
Result
, you may decide to suppress panics by adding theno_panic
flag:
#[shell(no_panic)]
Following return types are currently recognized:
return type | flags | on parse fail | on error exit code | on spawn fail | notes |
---|---|---|---|---|---|
- | panic | panic | |||
no_panic | - | nothing | nothing | ||
T | panic | panic | panic | 2 | |
T | no_panic | panic | panic | panic | 1,2 |
Result<T, E> | error | error | error | 2 | |
Result<T, E> | no_panic | error | error | error | 1,2 |
impl Iterator<Item=T> | panic | panic | panic | ||
impl Iterator<Item=T> | no_panic | ignore errors | ignore errors | empty iter | 3 |
impl Iterator<Item=Result<T, E>> | item error | panic | panic | 3 | |
impl Iterator<Item=Result<T, E>> | no_panic | item error | ignored | empty iter | |
Result<impl Iterator<Item=T>, E> | panic | ignored | error | ||
Result<impl Iterator<Item=T>, E> | no_panic | ignore errors | ignored | error | |
Result<impl Iterator<Item=Result<T, E1>>, E2> | item error | ignored | error | ||
Result<impl Iterator<Item=Result<T, E1>>, E2> | no_panic | item error | ignored | error | 1 |
Glossary:
action | meaning |
---|---|
panic | panics (.expect or panic!) |
nothing | consumes and ignores error (let _ = ...) |
error | returns error |
ignore errors | yields all successfuly parsed items, ignores parsing failures (flat_map) |
empty iter | returns empty iterator |
item error | when parsing fails, yields Err |
ignored | ignores exit code, behaves in the same way for exit code 0 and != 0 |
Notes:
- The
no_panic
attribute makes no difference - It reads all of stdout before producing any failures
- It yields all items until it encounters an error or an exit code
Enums
Error |
Functions
execute_iter_nopanic_nopanic | Executes command with args and environment variables, parses output line by line |
execute_iter_nopanic_result | Executes command with args and environment variables, parses output line by line |
execute_iter_panic_panic | Executes command with args and environment variables, parses output line by line |
execute_iter_panic_result | Executes command with args and environment variables, parses output line by line |
execute_iter_result_nopanic | Executes command with args and environment variables, parses output line by line |
execute_iter_result_panic | Executes command with args and environment variables, parses output line by line |
execute_iter_result_result | Executes command with args and environment variables, parses output line by line |
execute_parse_panic | Executes command with args and environment variables, parses output |
execute_parse_result | Executes command with args and environment variables, parses output |
execute_void_nopanic | Executes command with args and environment variables, ignores output |
execute_void_panic | Executes command with args and environment variables, ignores output |