[−][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 thecmdparameter:
#[shell(cmd = "python -c")]- by default, the script is added as the last argument. You can change it using the special variable
PROGRAMin thecmdparameter:
#[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_panicflag:
#[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_panicattribute 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 |