3 个版本
0.1.2 | 2024 年 8 月 4 日 |
---|---|
0.1.1 | 2024 年 6 月 6 日 |
0.1.0 | 2024 年 4 月 15 日 |
#484 在 Rust 模式
每月 137 次下载
19KB
90 行
声明式枚举分发生成
使用枚举生成特质的动态分发的模板代码。还为每个枚举变体生成 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 支持,所以... 可以)