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 where G: Display, { inner: Box, pub type_id: std::any::TypeId, pub member_id: G, } impl AnyOutput where G: Display, { #[cfg(feature = "general_renderer")] pub fn new(value: T) -> Self where 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 + Groupped + 'static, { Self { inner: Box::new(value), type_id: std::any::TypeId::of::(), member_id: T::member_id(), } } 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 where G: Display, { type Target = dyn std::any::Any + Send + 'static; fn deref(&self) -> &Self::Target { &*self.inner } } impl std::ops::DerefMut for AnyOutput where G: Display, { fn deref_mut(&mut self) -> &mut Self::Target { &mut *self.inner } } pub enum ChainProcess where G: Display, { Ok((AnyOutput, Next)), Err(ChainProcessError), } pub enum Next { Chain, Renderer, } impl ChainProcess where G: Display, { 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), } } }