2个不稳定版本
0.6.0 | 2024年3月2日 |
---|---|
0.5.0 | 2024年3月1日 |
0.4.0 |
|
0.3.0 |
|
0.1.0 |
|
#415 in 进程宏
9KB
76 行
Struct Morph
将一个结构体转换为另一个结构体的宏。
安装
cargo add struct_morph
或手动
struct_morph = "0.6"
使用方法
我偶尔会遇到这样的用例,即我有两个结构体表示非常相似的数据。它们共享大多数字段,有时甚至可以是其中一个的子集。比如说,我们有一个从数据库中来的结构体 ProductRow
,另一个结构体 ProductInfo
将作为API的JSON发送。
struct ProductRow {
id: i32,
name: String,
description: String,
available_count: i32,
base_price: i32,
discount: i32,
created_at: DateTime,
updated_at: DateTime,
}
struct ProductInfo {
id: i32,
name: String,
description: String,
is_available: bool,
price: i32,
}
现在,对于这个小案例,当我们需要将ProductRows转换为ProductInfos时,我们可以手动完成,但对于更大的结构体来说,这变得相当机械。
使用这个库,您可以编写以下内容
use struct_morph::{morph, morph_field};
#[morph(ProductRow)]
struct ProductInfo {
id: i32,
#[morph_field(select = name)]
title: String,
description: String,
#[morph_field(transform = "is_available")]
is_available: bool,
#[morph_field(transform = "net_price")]
price: i32,
}
fn is_available(value: &ProductRow) -> bool {
value.available_count > 0
}
fn net_price(value: &ProductRow) -> i32 {
value.base_price - value.discount
}
然后您可以从一个产品行简单地生成一个产品信息
let product_row: ProductRow = ProductRow {
id: 10,
name: "The Rust Programming Language".to_string(),
description: "The official book on the Rust programming language".to_string(),
available_count: 10,
base_price: 50,
discount: 10,
created_at: DateTime::now(),
updated_at: DateTime::now(),
};
let product_info: ProductInfo = ProductInfo::from(product_row);
这将复制具有相同名称(和类型)的字段的值,对于其余部分,可以提供自定义转换函数。它通过为源和目标结构体实现一个 From
特性来完成。
有两种类型字段修饰符
- 转换
#[morph_field(transform = "transform_func")]
这接受一个转换函数,该函数接受 &SourceStruct 作为参数并返回正确的类型
- 选择
#[morph_field(select = source_field)]
这接受一个源字段来替换字段的值
依赖项
~265–710KB
~17K SLoC