2个版本
0.1.1 | 2020年8月13日 |
---|---|
0.1.0 | 2020年8月13日 |
#21 在 #attr
在 sanitizeable 中使用
21KB
445 行
不要在生产环境中使用!
- 它使用了大量的
unsafe
,虽然已记录,但仅由我审核 - 它需要 nightly (
#![feature(untagged_unions)]
和#![feature(proc_macro_diagnostic)]
) - 生成的结构体总是
repr(C)
。
它做什么?
它允许您将结构体的字段标记为私有,并创建具有或不具有这些字段的变体。然后您可以引用每一个。
它还允许您只在其中一个或两个结构体上具有属性,并将容器消耗掉以将其转换为私有变体。
由于那会破坏内部布局保证,因此您可能不能在仅一个变体上使用 cfg
。
为什么创建这个?
我希望有自动的编译时保证,这样我就不会意外地公开私有数据。
示例
您可以在 这里 找到更多示例。
#![feature(untagged_unions)]
use sanitizeable::{sanitizeable, Sanitizeable};
#[sanitizeable]
#[derive(Debug)]
#[public_attr::derive(serde::Serialize)] // This only derives `serde::Serialize` for the public variant
struct User {
name: String,
// This attrribute is only applied to the field on the private type
#[private_attr::doc = "This is the user's email, make sure to send them a lot of spam"]
email: String,
#[private]
pin: u16,
}
// using `UserPrivate` here would not compile since it does not implement `serde::Serialize`
fn send_user_information<W: std::io::Write>(writer: &mut W, user_data: &UserPublic) {
eprintln!("sending user {}", user_data.name);
serde_json::to_writer(writer, user_data).unwrap();
// dbg!(user_data.pin); // This would not compile
}
fn change_pin(user: &mut UserPrivate, new_pin: u16) {
user.pin = new_pin;
}
fn main() {
let mut user_buffer = Vec::new();
let mut user = User::from_private(UserPrivate {
name: "A user".into(),
email: "[email protected]".into(),
pin: 1337,
});
send_user_information(&mut user_buffer, user.public());
change_pin(user.private_mut(), 42);
dbg!(user.public());
}
贡献
如果您认为这很酷并且想使其可使用,请随意创建 PR、Issue 或与我联系。
依赖项
~1.5MB
~35K SLoC