2 个版本
0.1.1 | 2019年2月16日 |
---|---|
0.1.0 | 2019年2月16日 |
#147 in #env-var
每月 123 次下载
在 8 个 库中使用(2 个直接使用)
30KB
574 行
概述
这是一个Rust属性类似的proc宏,可以减少调用shell命令和解析结果所需的代码量。
它允许您使用强类型函数将任何语言的脚本包装起来。函数的参数设置为环境变量,脚本的结果被解析为值或迭代器。
示例
基本
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}'
"# }
不同的解释器
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))
"# }
用法
您可以在具有以下属性的函数上使用 #[shell]
属性:
- 包含单个表达式(表示要执行的脚本的字符串字面量)的主体
- 实现了
.to_string()
方法的类型 - 返回值为
void
、T
、Result<T, E>
、impl Iterator<Item=T>
、Result<impl Iterator<Item=T>>
或Result<impl Iterator<Item=Result<T, E>>>
,具有约束
T: FromStr,
<T as FromStr>::Err: StdError,
E: From<shellfn::Error<<T as FromStr>::Err>>,
-
详细说明
#[shell]
属性执行以下操作:
- 将每个参数设置为一个环境变量
- 运行shell命令
- 使用
std::process::Command
启动命令 - 根据返回类型,它可能解析输出
大多数步骤都可以进行调整
- 默认命令是
bash -c
。您可以使用cmd
参数来更改它
#[shell(cmd = "python -c")]
- 默认情况下,脚本作为最后一个参数添加。您可以使用
PROGRAM
特殊变量在cmd
参数中更改它
#[shell(cmd = "bash -c PROGRAM -i")]
- 您可以在
cmd
参数中像在脚本中一样使用函数参数设置的环境变量
#[shell(cmd = "python -m $MODULE")]
fn run(module: &str)
- 如果返回类型不是在
Result
中包裹结果的一部分,您可以通过添加no_panic
标志来决定抑制恐慌
#[shell(no_panic)]
以下返回类型目前被识别
返回类型 | 标志 | 解析失败时 | 错误退出代码时 | 启动失败时 | 说明 |
---|---|---|---|---|---|
- | 恐慌 | 恐慌 | |||
no_panic | - | 无 | 无 | ||
() | - | 恐慌 | 恐慌 | ||
() | no_panic | - | 无 | 无 | |
Result<(), E> | - | 错误 | 错误 | ||
Result<(), E> | no_panic | - | 错误 | 错误 | 1 |
T | 恐慌 | 恐慌 | 恐慌 | 2 | |
T | no_panic | 恐慌 | 恐慌 | 恐慌 | 1,2 |
Result<T, E> | 错误 | 错误 | 错误 | 2 | |
Result<T, E> | no_panic | 错误 | 错误 | 错误 | 1,2 |
Vec | 恐慌 | 恐慌 | 恐慌 | ||
Vec | no_panic | 跳过 | 忽略 | 空 Vec | 3 |
Vec<Result<T, E>> | 项目错误 | 恐慌 | 恐慌 | ||
Vec<Result<T, E>> | no_panic | 项目错误 | 忽略 | 空 Vec | |
Result<Vec, E> | 恐慌 | 错误 | 错误 | ||
Result<Vec, E> | no_panic | 跳过 | 错误 | 错误 | |
Result<Vec<Result<T, E1>>, E2> | 项目错误 | 错误 | 错误 | ||
Result<Vec<Result<T, E1>>, E2> | no_panic | 项目错误 | 错误 | 错误 | 1 |
实现 Iterator<Item=T> | 恐慌 | 恐慌 | 恐慌 | ||
实现 Iterator<Item=T> | no_panic | 跳过 | 忽略 | 空迭代器 | 3 |
实现 Iterator<Item=Result<T, E>> | 项目错误 | 恐慌 | 恐慌 | 3 | |
实现 Iterator<Item=Result<T, E>> | no_panic | 项目错误 | 忽略 | 空迭代器 | |
Result<实现 Iterator<Item=T>, E> | 恐慌 | 忽略 | 错误 | ||
Result<实现 Iterator<Item=T>, E> | no_panic | 跳过 | 忽略 | 错误 | |
Result<实现 Iterator<Item=Result<T, E1>>, E2> | 项目错误 | 忽略 | 错误 | ||
Result<实现 Iterator<Item=Result<T, E1>>, E2> | no_panic | 项目错误 | 忽略 | 错误 | 1 |
术语表
动作 | 含义 |
---|---|
恐慌 | 恐慌 (.expect 或 panic!) |
无 | 消费并忽略错误 (let _ = ...) |
错误 | 返回错误 |
跳过 | 产生所有成功解析的项目,忽略解析失败 (filter_map) |
空迭代器/Vec | 返回空迭代器/向量 |
项目错误 | 解析失败时,产生 Err |
忽略 | 忽略退出代码,对退出代码 0 和 != 0 的行为相同 |
说明
no_panic
属性没有任何影响- 它读取所有 stdout 在产生任何失败之前
- 它产生所有项目,直到它遇到错误或退出代码
向量与迭代器
返回类型为 Vec
的变体与返回类型为 impl Iterator
的变体非常相似。关键区别在于
impl Iterator
只在必要时分配一个项目,并在解析后立即产生它,而Vec
是逐行读取输出,但将解析后的输出存储在临时的 Vec 中Vec
意识到退出代码。当子进程以错误状态完成时,impl Iterator
将停止产生值,而Vec
将返回错误或恐慌
贡献
所有贡献和评论都受到欢迎!不要害怕,无论何时发现错误或想改进这个 crate 的想法,都可以打开一个问题或 PR。
许可证
MIT 许可证
版权所有 (c) 2017 Marcin Sas-Szymański
特此授予任何获得本软件及其相关文档文件(“软件”)副本的任何人,免费使用该软件不受限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许向软件提供者提供软件的人这样做,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
本软件按“原样”提供,不提供任何形式的保证,无论是明示的、暗示的还是其他形式的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是在合同行为、侵权或其他行为中,无论源于、出于或与软件或软件的使用或其他方式相关。
依赖项
~460KB