7 个版本 (4 个重大更改)

0.5.1 2022年2月24日
0.5.0 2022年2月24日
0.4.0 2021年9月2日
0.3.0 2021年7月10日
0.1.0 2021年7月2日

#7 in #invariant

无许可证

9KB
194

prae

crates.io version docs.rs crates.io license

什么是 prae?

此包旨在提供一种更好的方式来定义需要验证的类型。 prae 不是 一个验证库,而是一个库,它 帮助开发者非常少的努力 定义需要验证的类型。

它是如何工作的?

使用 prae 的主要方式是通过 define! 宏。

例如,假设你想要创建一个 Username 类型。你希望这个类型是一个字符串,并且不希望它是空的。传统上,你会创建一个带有获取器和设置器的包装器结构体,如下面的简化示例所示

#[derive(Debug)]
pub struct Username(String);

impl Username {
    pub fn new(username: &str) -> Result<Self, &'static str> {
        let username = username.trim().to_owned();
        if username.is_empty() {
            Err("value is invalid")
        } else {
            Ok(Self(username))
        }
    }

    pub fn get(&self) -> &str {
        &self.0
    }

    pub fn set(&mut self, username: &str) -> Result<(), &'static str> {
        let username = username.trim().to_owned();
        if username.is_empty() {
            Err("value is invalid")
        } else {
            self.0 = username;
            Ok(())
        }
   }
}

let username = Username::new(" my username ").unwrap();
assert_eq!(username.get(), "my username");

let err = Username::new("  ").unwrap_err();
assert_eq!(err, "value is invalid");

使用 prae,你会这样做

use prae::define;

define! {
    pub Username: String
    adjust |username| *username = username.trim().to_owned()
    ensure |username| !username.is_empty()
}

let username = Username::new(" my username ").unwrap();
assert_eq!(username.get(), "my username");

let err = Username::new("  ").unwrap_err();
assert_eq!(err.inner, "value is invalid");
assert_eq!(err.value, "");

此外,prae 允许你使用自定义错误并扩展你的类型。有关更多信息,请参阅 文档

鸣谢

此包高度受到 tightness 包的启发。它基本上是 tightness 的一个分支,略有不同的理念。有关详细信息,请参阅 此问题

依赖项

~1.5MB
~35K SLoC