#derive #macro #from

derive-from-ext

实现结构体 'From' 的 Derive 宏

2 个不稳定版本

0.2.0 2022年4月14日
0.1.0 2022年4月3日

#23 in #from

26 每月下载量

MIT/Apache

15KB
219 代码行

derive-from-ext

一个 Derive 宏,自动为结构体实现 'std::convert::From'。默认行为是通过在源结构体属性上调用 .into() 来创建结构体实例。可以通过使用字段属性来重写默认行为,使用不同的名称和方法映射源结构体属性。

安装

在 Cargo.toml 文件中包含

[dependencies]
derive-from-ext = "0.2"

示例

use derive_from_ext::From;

struct A {
    prop1: String,
}

#[derive(From, Debug)]
#[from(A)]
struct B {
    prop1: String,
}

let a = A { prop1: "Test".to_string() };
let b: B = a.into();
dbg!(b); //automatically converted into type B and can use implementations on this type

默认值

如果源结构体属性比当前结构体少,则可以通过标记为 'skip' 来跳过属性

#[from(A)]
struct B [
    #[from(skip)]
    other_prop: String,
]

注意:这仅适用于可以分配默认值给属性值的情况,并且等价于将 skip 方法设置为 'std::default::Default::default',如下所示。

#[from(A)]
struct B [
    #[from(skip, default="String::from(\"New value\")")]
    other_prop: String,
]

替代方法

要使用替代方法创建结构体属性的值,可以使用属性路径的 met 属性

fn lowercase(str: String) -> String {
    str.to_lowercase()
}

#[from(A)]
struct B {
    #[from(map="lowercase")]
    other_prop: String,
}

不同的属性名称

要从源结构体的不同属性映射,可以使用属性属性

#[from(A)]
struct B {
    #[from(rename="prop1")]
    other_prop: String,
}

多个结构体

要支持多个源结构体,可以将 'from' 属性扩展以包含其他结构体。然后也可以覆盖每个源结构体的特定选项

#[from(A, B)]
struct C {
    #[from(overrides=( A=(skip=true), B=(map="lowercase") ))]
    other_prop: String,
}

替代方案

如果您不需要上述功能,只想将结构体转换为匹配的结构体,那么可能更适合使用 derive_more

依赖关系

~1.5MB
~35K SLoC