9 个版本
使用旧的 Rust 2015
0.3.0 | 2019 年 12 月 12 日 |
---|---|
0.2.3 | 2019 年 11 月 19 日 |
0.2.1 | 2019 年 1 月 25 日 |
0.2.0 | 2018 年 2 月 11 日 |
0.0.2 | 2018 年 2 月 4 日 |
2221 在 Rust 模式
16,447 每月下载量
用于 169 个包 (54 个直接使用)
32KB
568 行
shrinkwraprs
创建包装类型可以使我们给出关于代码正确性的更多编译时保证
// Now we can't mix up widths and heights; the compiler will yell at us!
struct Width(u64);
struct Height(u64);
但是...它们有点难用。如果你需要获取包装的 u64
,你需要不断进行模式匹配来包装和解包值。
shrinkwraprs
通过允许你通过派生 Shrinkwrap
来派生各种转换特性的实现来减轻这种痛苦。
实现的功能
目前,使用 #[derive(Shrinkwrap)]
将为所有结构体派生以下特性
AsRef<InnerType>
Borrow<InnerType>
Deref<Target=InnerType>
此外,使用 #[shrinkwrap(mutable)]
还将派生以下特性
AsMut<InnerType>
BorrowMut<InnerType>
DerefMut<Target=InnerType>
最后,还有一个选项是 #[shrinkwrap(transformers)]
,这将派生一些有用的固有函数来转换包装数据
fn transform<F>(&mut self, mut f:F) -> &mut Self whereF:FnMut(&mutInnerType)
fn siphon<F, T>(self, mut f:F) ->TwhereF:FnMut(InnerType)-> T
...其中 transform
使链式更新内部值变得容易,而 siphon
允许你轻松地将内部值移出以产生不同类型的值。
transform
将具有与内部字段相同的可见性,这确保了 transform
不会泄露改变内部值(可能以违反不变性的方式)的可能性。 siphon
的可见性与结构体本身相同,因为它 不 提供调用者直接破坏您数据的方法。
酷,我该如何使用它?
首先,在您的 Cargo.toml
中将 shrinkwraprs
添加为依赖项
[dependencies]
shrinkwraprs = "0.3.0"
然后,只需在您想方便化的任何结构体上贴上 #[derive(Shrinkwrap)]
#[macro_use] extern crate shrinkwraprs;
#[derive(Shrinkwrap)]
struct Email(String);
fn main() {
let email = Email("[email protected]".into());
let is_discriminated_email =
email.contains("+"); // Woohoo, we can use the email like a string!
/* ... */
}
如果您有多个字段,但只有一个字段您想能够解引用/借用,则使用 #[shrinkwrap(main_field)]
标记
#[derive(Shrinkwrap)]
struct Email {
spamminess: f64,
#[shrinkwrap(main_field)] addr: String
}
#[derive(Shrinkwrap)]
struct CodeSpan(u32, u32, #[shrinkwrap(main_field)] Token);
如果您还希望能够直接修改包装的值,还可以添加属性 #[shrinkwrap(mutable)]
#[derive(Shrinkwrap)]
#[shrinkwrap(mutable)]
struct InputBuffer {
buffer: String
}
...
let mut input_buffer = /* ... */;
input_buffer.push_str("some values");
...
依赖项
~2MB
~47K SLoC