#reflection #compile-time #duck #const-generics #typing #struct #field

nightly constduck

编译时 duck typing 和反射使用 const generics

1 个不稳定版本

0.1.0 2021 年 11 月 13 日

#2845 in Rust 模式

MPL-2.0 许可证

7KB

crates.io docs

constduck:编译时 duck typing 和反射

constduck 提供了一个 procmacro,可以启用任意结构类型上的编译时 duck typing 和反射。使用 constduck,你可以编写适用于任何具有正确字段的结构的泛型实现。它还允许你自动生成 trait 的实现,如 #[derive(..)],而无需 procmacro。请参阅 constduck/examples/debug-print.rs 中的示例。

用法

在结构体上派生 ConstDuck

#![feature(adt_const_params)]
use constduck::*;

#[derive(ConstDuck)]
struct Donald {
    money: i64,
}

这为结构体 Donald 实现了 Field<"money">ConstructFrom<T: WithField<"money">>。你可以使用这些特质来编写泛型实现。例如

fn deduct_money<N, T: Field<"money", Ty = N>>(t: &mut T) 
    where N: Clone,
        N: Sub<N, Output = N>,
        N: From<i8> {
    t.set(t.get().clone() - N::from(5i8));
}

deduct_money 将适用于任何具有字段 money 并派生 ConstDuck 的结构体。

constduck 的主要用途是在宏中,你想要使用字段的类型。例如

macro_rules! make_getter {
    ($struct:ident.$field:ident) => {
        impl $struct {
            pub fn $field(&self) -> &/* What to write here? */ {
                &self.$field
            }
        }
    }
}

struct Foo {
    bar: String,
    baz: u32,
}

make_getter!(Foo.bar);

在这种情况下,函数定义需要一个返回类型,但你没有足够的信息来指定类型。

(不稳定)

该项目需要 Rust nightly,并使用不完整的 adt_const_params 功能。你可能会遇到 ICEs。当前 API 在添加对元组结构和枚举的支持时可能会损坏。

许可证

constduck 采用 Mozilla Public License 2.0 (MPL2.0) 许可。请参阅 LICENSE 文件。

依赖关系

约 1.5MB
约 35K SLoC