#动态分发 #声明式宏 #特性 #枚举 #动态 #模板代码 #生成

declarative_enum_dispatch

生成枚举分发的模板代码的声明式宏

3 个版本

0.1.2 2024 年 8 月 4 日
0.1.1 2024 年 6 月 6 日
0.1.0 2024 年 4 月 15 日

#484Rust 模式

Download history 181/week @ 2024-06-01 17/week @ 2024-06-08 1/week @ 2024-06-15 13/week @ 2024-07-27 115/week @ 2024-08-03 9/week @ 2024-08-10

每月 137 次下载

MIT/Apache

19KB
90

声明式枚举分发生成

Crates.io docs.rs

使用枚举生成特质的动态分发的模板代码。还为每个枚举变体生成 From

这是 enum_dispatch 宏的完全声明式版本

有关基准测试,请参阅 enum_dispatch 基准测试

use declarative_enum_dispatch::enum_dispatch;

enum_dispatch!(
    /// Supports trait inheritance + lifetime (although single and after traits)
    pub trait ShapeTrait: Clone + std::fmt::Debug + 'static {
        /// No return + default implementation
        fn print_name(&self) {
            println!("name: `{}`", self.name());
        }
        /// Basic call without arguments
        fn name(&self) -> String;
        fn area(&self) -> i32;

        /// Mutable self + arguments
        fn grow(&mut self, numerator: i32, denominator: i32);

        /// Kinda supports generics :) Bot not generic parameters, only `impl Trait`
        fn greater(&self, other: &impl ShapeTrait) -> bool;
        
        /// Supports async methods
        async fn send(&self);

        /// Works with attributes
        #[cfg(feature = "platform_specific")]
        fn platform_specific(self);
    }

    #[derive(Debug, Clone)]
    pub enum Shape {
        Rect(Rect),
        Circle(Circle),
        #[cfg(feature = "platform_specific")]
        Cube(Cube)
    }
);

#[derive(Debug, Clone)]
pub struct Rect{ w: i32, h: i32 }

#[derive(Debug, Clone)]
pub struct Circle { r: i32 }

impl ShapeTrait for Rect {
    fn print_name(&self) {
        println!("rect name: `{}`", self.name());
    }
    fn name(&self) -> String {
        "Rect".to_string()
    }

    fn area(&self) -> i32 {
        self.w * self.h
    }

    fn grow(&mut self, numerator: i32, denominator: i32) {
        self.w = self.w * numerator / denominator;
        self.h = self.h * numerator / denominator;
    }

    fn greater(&self, other: &impl ShapeTrait) -> bool {
        self.area() > other.area()
    }

    async fn send(&self) {}
}

impl ShapeTrait for Circle {
    fn name(&self) -> String {
        "Circle".to_string()
    }

    fn area(&self) -> i32 {
        // close enough PI approximation :)
        3 * self.r * self.r
    }

    fn grow(&mut self, numerator: i32, denominator: i32 ) {
        self.r = self.r * numerator / denominator;
    }

    fn greater(&self, other: &impl ShapeTrait) -> bool {
        self.area() > other.area()
    }

    async fn send(&self) {}
}


assert_eq!(Shape::Rect(Rect { w: 1.0, h: 1.0 }).name(), "Rect".to_string());
assert_eq!(Shape::Circle(Circle { r: 1.0 }).name(), "Circle".to_string());

路线图

  • 支持泛型参数
  • 支持生命周期
  • 支持特性继承
  • 支持异步函数

为什么?

因为我可以... 好吧... RustRover 指数不支持枚举分发,在关于此问题的其中一个线程中我看到了

enum_dispatch 是一个罕见的不适合 IDE 的宏的例子。它打破了所有可以想象到的规则。按照当前的设计,enum_dispatch 永远不会得到支持。(来源)

所以我开始思考是否可以使用声明式宏来实现以获得“完美”的 IDE 支持,所以... 可以)

是的,我正在修复包以使其在我的付费 IDE 中正确索引。

我需要我的自动完成功能

没有运行时依赖