5 个版本
0.2.0 | 2024年2月12日 |
---|---|
0.1.3 | 2024年2月9日 |
0.1.2 | 2024年2月7日 |
0.1.1 | 2024年2月7日 |
0.1.0 | 2024年2月7日 |
2344 在 Rust 模式 中
每月 31 次下载
10KB
51 行
runtime-contracts
: 为 Rust 提供结构化、易于理解的运行时合约。
有关背景、上下文和使用示例,请参阅 crate 文档。
错误
如果您发现任何问题,请提交问题。欢迎提出建议!
路线图
- 可通过简单实用函数表达的结构化合约。
- 将合约作为函数/闭包。
- 这会像
type RuntimeContractFunction<T> = dyn Fn(T) -> Result<T>
那样简单,还是我们需要更多?
- 这会像
- 合约组合(假设我们至少想要单调组合)。
- 如果合约是函数,我们能否只使用函数组合?
- 我们需要或想要一个
RuntimeContract
结构来封装合约的特定信息,并提供Result
和Option
这样的组合子吗?
lib.rs
:
结构化、易于理解的运行时合约。
虽然许多语言都有合约库,但许多都选择仅在调试和测试构建中编译它们。这种选择的背后似乎是因为他们不希望在生产环境中承担性能损失。一个值得注意的例外是 Racket 的合约模块,它本身就是一个 杰作。在这个库中,我们为了运行时安全和程序正确性而放弃了这种担忧。
这个 crate 希望让构建软件的从业者更容易使用和理解基于合约的编程。其哲学直接受到著名计算机科学家、Dr. Betrand Meyer 在 1986 年设计 Eiffel 编程语言 时所表达的 设计-by-Contract (DbC) 概念的启发。
此外,还要感谢实现合约作为过程宏的 contracts
crate。绝对推荐您去看看!
示例
尽管这个示例使用了crate自己的错误类型,但只要它能工作,您可以用任何您想要的类型替换。
use runtime_contracts::{check, ensures, requires, error::RuntimeContractError, Result};
fn refund_loyalty_points(account_id: &str, point_amount: usize) -> Result<usize> {
requires(|| account_id.len() == 32, "malformed account ID")?;
requires(|| point_amount % 2 == 0, "attempting to refund an odd number of points")?;
let account = load_account(account_id);
let starting_balance = account.balance;
let closing_balance = account.add_to_balance(point_amount)?;
ensures(closing_balance, |balance| balance - point_amount == starting_balance, "points were not added to account")
}
依赖项
~295–750KB
~18K SLoC