summaryrefslogtreecommitdiff
path: root/mingling/src/any.rs
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-28 00:47:46 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-28 00:47:46 +0800
commit7ce68cd11516bd7cf037ecea99a92aee7c31b2c3 (patch)
treea3923ad41c91aa21fe169fd6b4b1bf8898a82589 /mingling/src/any.rs
Add initial Mingling framework codebase
Diffstat (limited to 'mingling/src/any.rs')
-rw-r--r--mingling/src/any.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/mingling/src/any.rs b/mingling/src/any.rs
new file mode 100644
index 0000000..a74cd54
--- /dev/null
+++ b/mingling/src/any.rs
@@ -0,0 +1,72 @@
+#[cfg(feature = "serde_renderer")]
+use serde::Serialize;
+
+use crate::error::ChainProcessError;
+
+pub type ChainProcess = Result<AnyOutput, ChainProcessError>;
+
+#[derive(Debug)]
+pub struct AnyOutput {
+ inner: Box<dyn std::any::Any + Send + 'static>,
+ type_id: std::any::TypeId,
+}
+
+impl AnyOutput {
+ #[cfg(feature = "serde_renderer")]
+ pub fn new<T>(value: T) -> Self
+ where
+ T: Send + Serialize + 'static,
+ {
+ Self {
+ inner: Box::new(value),
+ type_id: std::any::TypeId::of::<T>(),
+ }
+ }
+
+ #[cfg(not(feature = "serde_renderer"))]
+ pub fn new<T>(value: T) -> Self
+ where
+ T: Send + 'static,
+ {
+ Self {
+ inner: Box::new(value),
+ type_id: std::any::TypeId::of::<T>(),
+ }
+ }
+
+ pub fn downcast<T: 'static>(self) -> Result<T, Self> {
+ if self.type_id == std::any::TypeId::of::<T>() {
+ Ok(*self.inner.downcast::<T>().unwrap())
+ } else {
+ Err(self)
+ }
+ }
+
+ pub fn is<T: 'static>(&self) -> bool {
+ self.type_id == std::any::TypeId::of::<T>()
+ }
+
+ /// Route the output to the next Chain
+ pub fn route_chain(self) -> ChainProcess {
+ Ok(self)
+ }
+
+ /// Route the output to the Renderer, ending execution
+ pub fn route_renderer(self) -> ChainProcess {
+ Err(ChainProcessError::Broken(self))
+ }
+}
+
+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
+ }
+}