Mountain/Track/Effect/MappedEffectType.rs
1//! # MappedEffect (Track)
2//!
3//! ## RESPONSIBILITIES
4//!
5//! This module defines the MappedEffect type alias, which is the type-erased
6//! unit of work that the dispatch logic can execute.
7//!
8//! ## ARCHITECTURAL ROLE
9//!
10//! MappedEffect serves as the **effect abstraction** in Track's dispatch
11//! system:
12//!
13//! ```text
14//! Dispatch Logic ──► MappedEffect (Boxed Closure) ──► ApplicationRunTime Execution
15//! ```
16//!
17//! ## KEY COMPONENTS
18//!
19//! - **MappedEffect**: Type alias for boxed async closure signature
20//!
21//! ## ERROR HANDLING
22//!
23//! - All effects return Result<Value, String> for IPC compatibility
24//!
25//! ## LOGGING
26//!
27//! - Logging is handled by individual effect implementations
28//!
29//! ## PERFORMANCE CONSIDERATIONS
30//!
31//! - Boxed closure allocation is lightweight
32//! - Async operations avoid blocking
33//!
34//! ## TODO
35//!
36//! - [ ] Consider implementing an effect pool to cache frequently created
37//! effects
38
39use std::{future::Future, pin::Pin, sync::Arc};
40
41use serde_json::Value;
42
43use crate::RunTime::ApplicationRunTime::ApplicationRunTime;
44
45/// A type alias for a boxed, runnable effect. This is the "type-erased" unit of
46/// work that the dispatch logic can execute.
47pub type MappedEffect =
48 Box<dyn FnOnce(Arc<ApplicationRunTime>) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> + Send>;
49
50/// Wraps an async body into the full `MappedEffect` closure boilerplate.
51/// `$run_time` names the `Arc<ApplicationRunTime>` parameter inside the body.
52///
53/// Before:
54/// ```rust
55/// let effect = move |run_time: Arc<ApplicationRunTime>|
56/// -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
57/// Box::pin(async move { ... })
58/// };
59/// Some(Ok(Box::new(effect)))
60/// ```
61/// After: `effect!(run_time, { ... })`
62#[macro_export]
63macro_rules! effect {
64
65 ($run_time:ident, $body:block) => {{
66 let effect = move |$run_time: std::sync::Arc<
67 $crate::RunTime::ApplicationRunTime::ApplicationRunTime,
68
69 >|
70 -> std::pin::Pin<
71 Box<
72 dyn std::future::Future<Output = Result<serde_json::Value, String>>
73 + Send,
74
75 >,
76
77 > { Box::pin(async move $body) };
78
79 Some(Ok(
80 Box::new(effect) as $crate::Track::Effect::MappedEffectType::MappedEffect,
81 ))
82 }};
83}