#field #getter #macro-derive #type #compile-time

get-field-by-type

根据字段的类型获取字段的值

3 个版本

0.0.4 2024 年 3 月 1 日
0.0.3 2023 年 9 月 15 日
0.0.2 2023 年 6 月 27 日

#945Rust 模式

Download history 4/week @ 2024-03-17 14/week @ 2024-03-24 83/week @ 2024-03-31 35/week @ 2024-04-07 21/week @ 2024-04-14 10/week @ 2024-04-21 7/week @ 2024-05-05 10/week @ 2024-05-12 34/week @ 2024-05-19 32/week @ 2024-05-26 21/week @ 2024-06-02 17/week @ 2024-06-09 25/week @ 2024-06-16 17/week @ 2024-06-23 3/week @ 2024-06-30

64 每月下载量
4 个 crate 中使用 (通过 ezno-parser)

MIT 许可证

6KB

Get-field-by-type

crates.io badge docs.rs badge

基于字段的类型创建一个 getter。例如

use get_field_by_type::GetFieldByType;

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
enum Enum1 {
	A(i32, char),
	B(i32, bool),
	C(i32, String)
}

let x = Enum1::A(12, '!');
assert_eq!(*GetFieldByType::<i32>::get(&x), 12);

为什么不用 impl &Self for Into<&T>

在引用上使用 Into 来获取字段值是一种技巧。这是为获取具有常见类型的字段值而设计的。使用自定义 trait 也意味着未来的灵活性

其他选项和功能

当一个变体的结构体没有类型时,有两种行为

编译时错误(默认)

或指定的 语句 来评估。这可能是一个 panic

use get_field_by_type::GetFieldByType;

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
#[get_field_no_type_behavior(panic!("could not find item");)]
enum Enum2 {
	A(i32),
	B(i32),
	C
}

assert_eq!(*GetFieldByType::<i32>::get(&Enum2::A(12)), 12);

let result = std::panic::catch_unwind(|| {
	let _value = *GetFieldByType::<i32>::get(&Enum2::C);
});
assert!(result.is_err());

或返回一个常量值

use get_field_by_type::GetFieldByType;

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
#[get_field_no_type_behavior(return &0;)]
enum Enum2 {
	A(i32),
	B(i32),
	C
}

assert_eq!(*GetFieldByType::<i32>::get(&Enum2::A(12)), 12);
assert_eq!(*GetFieldByType::<i32>::get(&Enum2::C), 0);

对单元变体递归

AOrB 枚举的情况下, derive 宏无法在变体 AOrB::A 上找到 i32。然而,因为它是一个单元变体,实现将其委托给单元类型。

use get_field_by_type::GetFieldByType;

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
struct A(pub i32);

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
struct B(pub i32);

#[derive(GetFieldByType)]
#[get_field_by_type_target(i32)]
enum AOrB {
	A(A),
	B(B)
}

let b = B(10);
assert_eq!(*GetFieldByType::<i32>::get(&b), 10);

let a_or_b = AOrB::B(b);
assert_eq!(*GetFieldByType::<i32>::get(&a_or_b), 10);

替代方案

对于更手动的字段访问,请查看 getset。如果您正在寻找获取多个字段,请查看 getters-by-type

依赖关系

~335–780KB
~19K SLoC