10个版本 (4个重大更新)
0.5.6 | 2024年1月20日 |
---|---|
0.5.5 | 2023年12月5日 |
0.4.5 | 2023年12月4日 |
0.3.0 | 2023年10月24日 |
0.1.2 | 2023年1月16日 |
#852 在 过程宏
用于 rikka-mq
18KB
177 行
解构模式自动化
destructure
是一个针对 destructure pattern
的自动化库。
什么是 destructure pattern
?
具有太多字段的结构难以调用构造函数,但为每个字段准备 Getter/Setter
也很费时。为此存在宏,但即使是大量宏也会降低可读性。这在使用 From<T>
特性时尤为明显。
那么如何简化这一点呢?这就是“将所有字段转换为公共字段”的技术。
这允许进行简化表示,如下例所示
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}
impl AuthenticateResponse {
pub fn into_destruct(self) -> DestructAuthenticateResponse {
DestructAuthenticateResponse {
id: self.id,
user_code: self.user_code,
verification_uri: self.verification_uri,
expires_in: self.expires_in,
message: self.message,
// ...
}
}
}
pub struct DestructAuthenticateResponse {
pub id: Uuid,
pub user_code: String,
pub verification_uri: String,
pub expires_in: i32,
pub message: String,
// ... too many fields (All `public`.)...
}
#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::<AuthenticateResponse>().await.unwrap();
let des = res.into_destruct();
println!("{:?}", des.id);
}
这种方法有几个问题,其中最严重的是样板代码的增加。
使用编辑器的多光标功能,可以通过复制粘贴来完成,但这仍然很麻烦。
因此,我创建了一个 过程宏,可以自动生成结构和方法
use destructure::Destructure;
#[derive(Destructure)]
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}
#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::<AuthenticateResponse>().await.unwrap();
// Auto generate
let des: DestructAuthenticateResponse = res.into_destruct();
println!("{:?}", des.id);
}
您还可以通过使用 reconstruct()
或 substitute()
来执行安全值替换,
它们与以下用法具有相同的功能。
use destructure::{Destructure, Mutation};
#[derive(Destructure, Mutation)]
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}
#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::<AuthenticateResponse>().await.unwrap();
let message = "After".to_string();
// `reconstruct()` consumes self and provides the Destructed structure
// as a variable reference in a closure.
// Literally, it is a method that reconstructs.
let res: AuthenticateResponse = res.reconstruct(|before| {
before.message = message;
});
// substitute is a method that refills variable references of its own field values
// into another structure and provides them in a closure.
//
// This method is suitable for loop processing, etc.,
// because it processes by reference as opposed to reconstruct, which consumes values.
let mut res = res;
res.substitute(|before| {
*before.message = message;
});
println!("{:?}", des.id);
}
问题
功能仍然有限,但如果出现任何问题,我们将接受PullRequests和Issues。
依赖项
~320–780KB
~19K SLoC