#macro #language #programming #programming-language #invariants #checking #guard

eiffel

艾菲尔是一个受Rust宏启发的艾菲尔语言守卫子句的库

4个版本

0.0.4 2024年2月28日
0.0.3 2024年2月28日
0.0.2 2024年2月28日
0.0.1 2017年10月30日

#84 in 过程宏

Download history 2/week @ 2024-03-15 24/week @ 2024-03-29 6/week @ 2024-04-05

69 每月下载量

MIT许可证

14KB
126

eiffel

Build & Test Build & Test against latest dependencies

这是一个仅用于个人测试的项目,但可以工作。一个具有直接表达式的类似包是contracts,当然还有原始的LibHoare

请参考它们进行生产使用。

此包提供了一组受艾菲尔编程语言不变量检查功能启发的宏。艾菲尔语言的不变量检查选项是此包中宏设计和功能的基础。

请注意,此包仍在开发中。因此,某些功能可能尚未完全实现,或在未来更新中可能发生重大变化。我们始终欢迎贡献和反馈,但假设上述包替代品是更好的协作目标。

使用方法?

艾菲尔语言以其非常健壮的契约设计和断言而闻名,我在20世纪90年代初第一次看到它时就立刻爱上了它。

由于Rust比C等语言有更好的宏环境,因此很明显我们可以以这种方式扩展Rust。

一个虚构的艾菲尔示例

  set_second (s: INTEGER)
      -- Set the second from `s'.
    require
      valid_argument_for_second: 0 <= s and s <= 59
    do
      second := s
    ensure
      second_set: second = s
    end

在rust中

use eiffel::contract;

struct UnitBetween1And20 {
  val: u8
}

impl UnitBetween1And20 {
  fn new() -> Self {
    Self { val: 1 }
  }

  fn is_valid_val(&self) -> bool {
    self.val >= 1 && self.val <= 20
  }

  #[contract(is_valid_val)]
  pub fn inc(&mut self) {
    self.val += 1;
  }

  #[contract(is_valid_val)]
  pub fn set(&mut self, new_value: u8) {
    self.val = new_value;
  }
}

let mut a = UnitBetween1And20::new();
a.inc();

// Note: Inside the crate we could still do an unchecked
// direct access.
a.val = 20;

// This would fail with a panic! now:
// 
// a.inc();

待办事项

此包需要更紧密地与艾菲尔保持一致。例如,缺少ensure,应该取消对单独函数的要求,并允许原地表达式返回布尔值。

如果它还能为它标记的函数添加额外的文档,使其'契约'在文档中可见,那就太棒了。但似乎目前宏还做不到。

开发工作流程

  • 安装rust
  • 配置稳定工具链
    • rustup更新稳定版 && rustup默认稳定版
  • 在本地机器上构建项目
    • cargo构建 --工作空间
  • 测试
    • cargo测试 --工作空间
    • cargo测试 --工作空间 --文档
  • 安装 cargo-watch 工具以实现持续重建等。
    • cargo安装 cargo-watch
    • cargo watch --clear -x "build"cargo watch --clear -x "test --workspace --doc"

Cargo.toml 包含了对子 crate 的链接,因为 Rust 默认情况下不能让不同的宏位于同一个 crate 中。这就是我们重新暴露的原因。

遗憾的是,这意味着在发布到主分支之前,我们必须手动更新 Cargo.toml 中的依赖版本。

我将尝试使用 release-plz 来自动化推送新版本,但到目前为止我对此并不满意。

依赖项

~310–780KB
~18K SLoC