22 个版本
0.8.4 | 2022 年 6 月 16 日 |
---|---|
0.8.2 | 2022 年 3 月 18 日 |
0.6.0 | 2021 年 9 月 2 日 |
0.5.1 | 2021 年 7 月 11 日 |
#1028 in 开发工具
219 每月下载量
37KB
474 行
prae
prae
是一个旨在提供更好的方式来定义需要验证的类型的大 crate。
库的主要概念是 Wrapper
trait。此 trait 描述了一个包含某些内部值并提供构建、读取和修改它的方法的 Newtype
包装结构体。
创建实现 Wrapper
的类型的最简单方法是使用 define!
和 extend!
宏。
示例
假设你想要创建一个类型 Username
。你希望这个类型是 String
,并且你不希望它为空。传统上,你会创建一个包装结构体,带有获取器和设置器函数,如下面的简化示例所示
#[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::Wrapper;
prae::define! {
#[derive(Debug)]
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.original, "value is invalid");
assert_eq!(err.value, "");
此外,prae
允许你使用自定义错误并扩展你的类型。有关 define!
和 extend!
的更多信息,请参阅文档和示例。
编译速度
此 crate 提供的宏是声明性的,因此对编译速度几乎没有影响。
性能影响
如果你发现自己处于一个内部调整和验证你的类型成为性能瓶颈的情况(例如,你执行了重量级验证并在热点循环中修改了你的类型) - 尝试使用 _unprocessed
变体 [Wrapper
] 方法。它们不会调用 [Wrapper::PROCESS
]。然而,我强烈建议你在这些操作之后调用 [Wrapper::verify
]。
特性标志
prae
提供了额外的功能
名称 | 描述 |
---|---|
serde |
添加了 [impl_serde ] 插件。 |
致谢
这个软件包高度受到 tightness 软件包的启发。它基本上是 tightness 的一个分支,但有着略微不同的理念。有关详细信息,请参阅 这个问题。
许可证:Unlicense
依赖项
~165KB