2 个版本
0.1.1 | 2020 年 8 月 13 日 |
---|---|
0.1.0 | 2020 年 8 月 13 日 |
#2311 在 Rust 模式
4KB
55 行
不要在生产环境中使用!
- 它使用了很多
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
~33K SLoC