aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mingling_core/src/any/group.rs16
-rw-r--r--mingling_core/src/asset.rs3
-rw-r--r--mingling_core/src/asset/routable.rs22
-rw-r--r--mingling_core/src/lib.rs1
-rw-r--r--mingling_macros/src/lib.rs43
5 files changed, 76 insertions, 9 deletions
diff --git a/mingling_core/src/any/group.rs b/mingling_core/src/any/group.rs
index 14663db..90ef9fc 100644
--- a/mingling_core/src/any/group.rs
+++ b/mingling_core/src/any/group.rs
@@ -1,4 +1,4 @@
-use crate::{AnyOutput, ChainProcess};
+use crate::{AnyOutput, ChainProcess, ProgramCollect, Routable};
/// Used to mark a type with a unique enum ID, assisting dynamic dispatch
///
@@ -32,3 +32,17 @@ where
AnyOutput::new(self).route_renderer()
}
}
+
+impl<T, C> Routable<C> for T
+where
+ C: ProgramCollect<Enum = C>,
+ T: Grouped<C> + Send,
+{
+ fn to_chain(self) -> ChainProcess<C> {
+ T::to_chain(self)
+ }
+
+ fn to_render(self) -> ChainProcess<C> {
+ T::to_render(self)
+ }
+}
diff --git a/mingling_core/src/asset.rs b/mingling_core/src/asset.rs
index b1fd617..9b9a5d4 100644
--- a/mingling_core/src/asset.rs
+++ b/mingling_core/src/asset.rs
@@ -21,3 +21,6 @@ pub mod node;
#[doc(hidden)]
pub mod renderer;
+
+#[doc(hidden)]
+pub mod routable;
diff --git a/mingling_core/src/asset/routable.rs b/mingling_core/src/asset/routable.rs
new file mode 100644
index 0000000..24b7bb1
--- /dev/null
+++ b/mingling_core/src/asset/routable.rs
@@ -0,0 +1,22 @@
+use crate::ChainProcess;
+
+/// Provides routing capabilities for converting an item into a `ChainProcess`
+/// directed to either the chain or render processing pipeline.
+///
+/// This trait enables items to be dispatched to different processing routes
+/// (chain or render) by wrapping them into an `AnyOutput` and routing them
+/// through the appropriate pipeline.
+pub trait Routable<Group>
+where
+ Self: Sized + 'static,
+{
+ /// Converts the routable item into a `ChainProcess` directed to the chain route.
+ ///
+ /// This wraps the item into an `AnyOutput` and routes it to the chain processing pipeline.
+ fn to_chain(self) -> ChainProcess<Group>;
+
+ /// Converts the routable item into a `ChainProcess` directed to the render route.
+ ///
+ /// This wraps the item into an `AnyOutput` and routes it to the render processing pipeline.
+ fn to_render(self) -> ChainProcess<Group>;
+}
diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs
index 3c2cf9b..4996b19 100644
--- a/mingling_core/src/lib.rs
+++ b/mingling_core/src/lib.rs
@@ -36,6 +36,7 @@ pub use crate::asset::help::*;
pub use crate::asset::lazy_resource::*;
pub use crate::asset::node::*;
pub use crate::asset::renderer::*;
+pub use crate::asset::routable::*;
/// All error types of `Mingling`
pub mod error {
diff --git a/mingling_macros/src/lib.rs b/mingling_macros/src/lib.rs
index 77e1137..ea33577 100644
--- a/mingling_macros/src/lib.rs
+++ b/mingling_macros/src/lib.rs
@@ -521,20 +521,25 @@ pub fn pack_err_structural(input: TokenStream) -> TokenStream {
pack_err::pack_err_structural(input)
}
-/// Early-returns an error from a `Result`, converting the `Ok` branch to a
-/// `ChainProcess`.
+/// Early-returns the error from a `Result`, converting the `Ok` branch to the
+/// next chain process value.
///
/// This macro is equivalent to:
/// ```rust,ignore
/// match expr {
/// Ok(r) => r,
-/// Err(e) => return ::mingling::Grouped::to_chain(e),
+/// Err(e) => return ::mingling::Routable::to_chain(e),
/// }
/// ```
///
-/// It is useful inside chain functions where you have a `Result<SomeType, SomeType>`
-/// where both types implement `Grouped` and want to propagate the error case
-/// as an early return via `Grouped::to_chain()`.
+/// It is useful inside chain functions where you have a `Result<SuccessType, ErrorType>`
+/// where both types implement `Routable` and you want to propagate the error case
+/// as an early return via `Routable::to_chain()`.
+///
+/// The key difference from a simple `?` operator is that `route!` converts **both**
+/// the success and error types into the chain process — the `Ok` value is unwrapped
+/// directly, while the `Err` value is converted via `Routable::to_chain()` and
+/// returned early.
///
/// # Example
///
@@ -542,7 +547,7 @@ pub fn pack_err_structural(input: TokenStream) -> TokenStream {
/// use mingling::macros::{chain, route};
///
/// #[chain]
-/// fn process(prev: SomeEntry) -> ChainProcess<ThisProgram> {
+/// fn process(prev: SomeEntry) -> Next {
/// let value = route!(current_dir().map_err(|e| ErrorEntry::new(e.to_string_lossy().to_string())));
/// // value is the PathBuf from current_dir()
/// value.to_chain()
@@ -555,7 +560,7 @@ pub fn route(input: TokenStream) -> TokenStream {
let expanded = quote! {
match #expr {
Ok(r) => r,
- Err(e) => return ::mingling::Grouped::to_chain(e),
+ Err(e) => return ::mingling::Routable::to_chain(e),
}
};
TokenStream::from(expanded)
@@ -1446,8 +1451,30 @@ pub fn gen_program(_input: TokenStream) -> TokenStream {
let comp_gen = quote! {};
TokenStream::from(quote! {
+ /// Alias for the current program type `crate::ThisProgram`
pub type Next = ::mingling::ChainProcess<crate::ThisProgram>;
+ impl ::mingling::Routable<crate::ThisProgram> for ::mingling::ChainProcess<crate::ThisProgram>
+ {
+ fn to_chain(self) -> ::mingling::ChainProcess<crate::ThisProgram> {
+ match self {
+ ::mingling::ChainProcess::Ok((any, _)) => {
+ ::mingling::ChainProcess::Ok((any, mingling::NextProcess::Chain))
+ }
+ other => other,
+ }
+ }
+
+ fn to_render(self) -> ::mingling::ChainProcess<crate::ThisProgram> {
+ match self {
+ ::mingling::ChainProcess::Ok((any, _)) => {
+ ::mingling::ChainProcess::Ok((any, mingling::NextProcess::Renderer))
+ }
+ other => other,
+ }
+ }
+ }
+
#comp_gen
::mingling::macros::program_fallback_gen!();
::mingling::macros::program_final_gen!();