From 596e5e2440df2d32f1cf3e052dc633e774edf6ee Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 29 Mar 2026 21:48:23 +0800 Subject: Rename mingling to mingling_core and update dependencies --- mingling_core/src/any.rs | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 mingling_core/src/any.rs (limited to 'mingling_core/src/any.rs') diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs new file mode 100644 index 0000000..1bce96a --- /dev/null +++ b/mingling_core/src/any.rs @@ -0,0 +1,128 @@ +#[cfg(feature = "general_renderer")] +use serde::Serialize; + +use crate::error::ChainProcessError; + +#[derive(Debug)] +pub struct AnyOutput { + inner: Box, + pub type_id: std::any::TypeId, +} + +impl AnyOutput { + #[cfg(feature = "general_renderer")] + pub fn new(value: T) -> Self + where + T: Send + Serialize + 'static, + { + Self { + inner: Box::new(value), + type_id: std::any::TypeId::of::(), + } + } + + #[cfg(not(feature = "general_renderer"))] + pub fn new(value: T) -> Self + where + T: Send + 'static, + { + Self { + inner: Box::new(value), + type_id: std::any::TypeId::of::(), + } + } + + pub fn downcast(self) -> Result { + if self.type_id == std::any::TypeId::of::() { + Ok(*self.inner.downcast::().unwrap()) + } else { + Err(self) + } + } + + pub fn is(&self) -> bool { + self.type_id == std::any::TypeId::of::() + } + + /// Route the output to the next Chain + 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 { + ChainProcess::Ok((self, Next::Renderer)) + } +} + +impl std::ops::Deref for AnyOutput { + type Target = dyn std::any::Any + Send + 'static; + + fn deref(&self) -> &Self::Target { + &*self.inner + } +} + +impl std::ops::DerefMut for AnyOutput { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut *self.inner + } +} + +pub enum ChainProcess { + Ok((AnyOutput, Next)), + Err(ChainProcessError), +} + +pub enum Next { + Chain, + Renderer, +} + +impl ChainProcess { + pub fn is_next(&self) -> bool { + matches!(self, Self::Ok(_)) + } + + pub fn is_err(&self) -> bool { + matches!(self, Self::Err(_)) + } + + pub fn next(&self) -> Option<&Next> { + match self { + Self::Ok((_, next)) => Some(next), + Self::Err(_) => None, + } + } + + pub fn err(&self) -> Option<&ChainProcessError> { + match self { + Self::Ok(_) => None, + Self::Err(err) => Some(err), + } + } + + 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) { + match self { + Self::Ok(tuple) => tuple, + Self::Err(_) => default, + } + } + + pub fn unwrap_or_else(self, f: F) -> (AnyOutput, Next) + where + F: FnOnce(ChainProcessError) -> (AnyOutput, Next), + { + match self { + Self::Ok(tuple) => tuple, + Self::Err(err) => f(err), + } + } +} -- cgit