4 个版本
0.2.1 | 2024 年 1 月 20 日 |
---|---|
0.2.0 | 2023 年 11 月 4 日 |
0.1.1 | 2023 年 10 月 31 日 |
0.1.0 | 2023 年 9 月 17 日 |
在 #partial 中排名 #67
每月下载量 146
用于 部分
51KB
961 行代码(不含注释)
部分
提供可配置的 推导宏,该宏生成另一个具有相同字段的结构体,但字段被包裹在
Option<T>
中,并实现Partial
以允许有条件地将生成的结构体字段应用于基本结构体字段。
部分
提供了 Partial
trait,允许将另一个结构体的值应用于 self
,意图是另一个结构体反映 self
的字段,但被包裹在 Option<T>
中。
此外,部分推导
(或启用 derive
功能的 部分
)支持自动生成一个镜像结构体,每个字段都被包裹在 Option<T>
中,并生成一个 Partial
实现,允许将镜像结构体的 Some
字段应用于基本结构体。我预计大多数人会对使用推导宏感兴趣。
使用方法
使用 derive
// `partially` installed with feature `derive`
use partially::Partial;
// define a base structure, with the `Partial` derive macro
#[derive(Partial)]
// further, instruct the macro to derive `Default` on the generated structure
#[partially(derive(Default))]
struct Data {
// since no field options are specified, this field will be mapped
// to an `Option<String>` in the generated structure
value: String,
}
// example usage
fn main() {
// since we derived default for the generated struct, we can use that
// to obtain a partial struct filled with `None`.
let empty_partial = PartialData::default();
// we can, of course, also specify values ourself
let full_partial = PartialData {
value: Some("modified".to_string()),
};
// define a "base" that we'll operate against
let mut full = Data {
value: "initial".to_string(),
};
// apply the empty partial (note that `false` is returned, indicating nothing was applied)
assert!(!full.apply_some(empty_partial));
// note that applying the empty partial had no effect
assert_eq!(full.value, "initial".to_string());
// apply the full partial (note that `true` is returned, indicating something was applied)
assert!(full.apply_some(full_partial));
// note that applying the full partial modified the value
assert_eq!(full.value, "modified".to_string());
}
不使用 derive
use partially::Partial;
struct Base {
value: String,
}
#[derive(Default)]
struct PartialBase {
value: Option<String>,
}
impl Partial for Base {
type Item = PartialBase;
#[allow(clippy::useless_conversion)]
fn apply_some(&mut self, partial: Self::Item) -> bool {
let will_apply_some = partial.value.is_some();
if let Some(value) = partial.value {
self.value = value.into();
}
will_apply_some
}
}
fn main() {
let empty_partial = PartialBase::default();
let full_partial = PartialBase {
value: Some("modified".to_string()),
};
let mut data = Base {
value: "initial".to_string(),
};
assert!(!data.apply_some(empty_partial));
assert_eq!(data.value, "initial".to_string());
assert!(data.apply_some(full_partial));
assert_eq!(data.value, "modified".to_string())
}
结构体选项
derive
使用示例:
#[部分(derive(Debug, Default))]
。
指示宏在生成的结构体上生成一个 #[derive(...)]
属性。
注意:当与 skip_attributes
选项一起使用时,仍然会将 derive 属性添加到生成的结构体中。
rename
使用示例:
#[partially(rename = "MyGeneratedStruct")]
。
指示宏使用给定的标识符为生成的结构体。默认情况下,使用 PartialBaseStructName
,其中 BaseStructName
是原始结构体的名称。
attribute
使用示例:
#[partially(attribute(serde(rename_all = "PascalCase")))]
指示宏向生成的结构体添加额外的属性。默认情况下,将基础结构体上定义的属性转发到生成的结构体,除非存在 skip_attributes
选项。
skip_attributes
使用示例:
#[partially(skip_attributes)]
。
指示宏跳过从原始结构体到生成结构体的属性转发。默认情况下,所有存在于基础结构体上的属性都将添加到生成的结构体中。
注意:当与 derive
选项一起使用时,derive 属性 仍然会被添加到生成的结构体中。
注意:当与 attribute
选项一起使用时,指定的属性 仍然会被添加到生成的结构体中。
crate
使用示例:
#[partially(crate = "my_partially_crate")]
。
指示宏使用不同的基础路径进行 Partial
特性实现。默认情况下使用 partially
。如果你已经分叉了 partially
crate,这可能会很有用。
字段选项
rename
使用示例:
#[partially(rename = "new_field_name")]
。
指示宏使用指定的标识符来为生成的字段命名。默认情况下,使用与基本结构相同的名称。
省略
使用示例:
#[partially(omit)]
。
指示宏从生成的结构体中省略该字段。默认情况下,不省略任何字段。
透明
使用示例:
#[partially(transparent)]
。
指示宏跳过将生成的字段包装在 Option<T>
中,而是透明地将字段类型映射到生成的结构体中。
as_type
使用示例:
#[partially(as_type = "Option<f32>")]
。
指示宏在生成字段时使用提供的类型,而不是 Option<T>
。请注意,提供的类型将直接使用,因此如果您期望一个 Option<T>
值,则需要手动指定。
注意:当使用 as_type
时,给定类型必须 Into<BaseType>
,其中 BaseType
是原始字段类型。这是 Partial
特性实现所必需的。
依赖
~0.6–1.1MB
~25K SLoC