From 3de10ca22cca06c4d9069984d0e66e370a331dde Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Wed, 1 Apr 2026 15:48:41 +0800 Subject: Replace typeid-based dispatch with enum-based dispatch - Add `Groupped` trait and `member_id` to `AnyOutput` - Add generic parameter `G` to `Dispatcher`, `Chain`, `Program` etc - Remove `hint` module and its marker types - Update macros to support explicit group specification - Add `gen_program` macro for generating enum-based programs - Add `GroupProcess` marker type for type-level grouping --- mingling_core/src/any.rs | 56 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 15 deletions(-) (limited to 'mingling_core/src/any.rs') diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs index 1bce96a..dac0d44 100644 --- a/mingling_core/src/any.rs +++ b/mingling_core/src/any.rs @@ -1,34 +1,48 @@ +use std::fmt::Display; + #[cfg(feature = "general_renderer")] use serde::Serialize; +use crate::Groupped; use crate::error::ChainProcessError; +pub mod group; + #[derive(Debug)] -pub struct AnyOutput { +pub struct AnyOutput +where + G: Display, +{ inner: Box, pub type_id: std::any::TypeId, + pub member_id: G, } -impl AnyOutput { +impl AnyOutput +where + G: Display, +{ #[cfg(feature = "general_renderer")] pub fn new(value: T) -> Self where - T: Send + Serialize + 'static, + T: Send + Groupped + Serialize + 'static, { Self { inner: Box::new(value), type_id: std::any::TypeId::of::(), + member_id: T::member_id(), } } #[cfg(not(feature = "general_renderer"))] pub fn new(value: T) -> Self where - T: Send + 'static, + T: Send + Groupped + 'static, { Self { inner: Box::new(value), type_id: std::any::TypeId::of::(), + member_id: T::member_id(), } } @@ -45,17 +59,20 @@ impl AnyOutput { } /// Route the output to the next Chain - pub fn route_chain(self) -> ChainProcess { + pub fn route_chain(self) -> ChainProcess { ChainProcess::Ok((self, Next::Chain)) } /// Route the output to the Renderer, ending execution - pub fn route_renderer(self) -> ChainProcess { + pub fn route_renderer(self) -> ChainProcess { ChainProcess::Ok((self, Next::Renderer)) } } -impl std::ops::Deref for AnyOutput { +impl std::ops::Deref for AnyOutput +where + G: Display, +{ type Target = dyn std::any::Any + Send + 'static; fn deref(&self) -> &Self::Target { @@ -63,14 +80,20 @@ impl std::ops::Deref for AnyOutput { } } -impl std::ops::DerefMut for AnyOutput { +impl std::ops::DerefMut for AnyOutput +where + G: Display, +{ fn deref_mut(&mut self) -> &mut Self::Target { &mut *self.inner } } -pub enum ChainProcess { - Ok((AnyOutput, Next)), +pub enum ChainProcess +where + G: Display, +{ + Ok((AnyOutput, Next)), Err(ChainProcessError), } @@ -79,7 +102,10 @@ pub enum Next { Renderer, } -impl ChainProcess { +impl ChainProcess +where + G: Display, +{ pub fn is_next(&self) -> bool { matches!(self, Self::Ok(_)) } @@ -102,23 +128,23 @@ impl ChainProcess { } } - pub fn unwrap(self) -> (AnyOutput, Next) { + pub fn unwrap(self) -> (AnyOutput, Next) { match self { Self::Ok(tuple) => tuple, Self::Err(_) => panic!("called `ChainProcess2::unwrap()` on an `Error` value"), } } - pub fn unwrap_or(self, default: (AnyOutput, Next)) -> (AnyOutput, Next) { + pub fn unwrap_or(self, default: (AnyOutput, Next)) -> (AnyOutput, Next) { match self { Self::Ok(tuple) => tuple, Self::Err(_) => default, } } - pub fn unwrap_or_else(self, f: F) -> (AnyOutput, Next) + pub fn unwrap_or_else(self, f: F) -> (AnyOutput, Next) where - F: FnOnce(ChainProcessError) -> (AnyOutput, Next), + F: FnOnce(ChainProcessError) -> (AnyOutput, Next), { match self { Self::Ok(tuple) => tuple, -- cgit