torrust_tracker_deployer_lib/presentation/cli/dispatch/mod.rs
1//! Dispatch Layer - Presentation Layer Component
2//!
3//! The Dispatch Layer is responsible for routing parsed commands to their appropriate handlers
4//! and providing execution context for command processing. This is the second layer in the
5//! presentation layer's four-layer architecture: Input → Dispatch → Controllers → Views.
6//!
7//! ## Purpose
8//!
9//! The Dispatch Layer establishes clear separation between:
10//! - **Command routing** (determining which handler to execute)
11//! - **Execution context** (providing dependencies to handlers)
12//! - **Command execution** (actual command logic in Controllers layer)
13//! - **Result presentation** (handled by Views layer)
14//!
15//! This separation provides several benefits:
16//! - **Single Responsibility**: Routing logic isolated from command execution
17//! - **Testability**: Router can be tested independently of command handlers
18//! - **Dependency Injection**: Clean pattern for providing services to commands
19//! - **Scalability**: Easy to add new commands without modifying existing handlers
20//!
21//! ## Module Structure
22//!
23//! ```text
24//! dispatch/
25//! ├── mod.rs # This file - layer exports and documentation
26//! ├── router.rs # Command routing logic (route_command function)
27//! └── context.rs # ExecutionContext wrapper around Container
28//! ```
29//!
30//! ## `ExecutionContext` Design
31//!
32//! The Dispatch Layer uses an `ExecutionContext` wrapper around the `Container` rather than
33//! passing the `Container` directly to command handlers. This design choice provides several
34//! important benefits:
35//!
36//! ### 1. Future-Proof Command Signatures
37//!
38//! By using `ExecutionContext`, we can extend execution context in the future without
39//! breaking existing command handler signatures:
40//!
41//! ```rust,ignore
42//! use std::sync::Arc;
43//! use torrust_tracker_deployer_lib::bootstrap::Container;
44//!
45//! pub struct ExecutionContext {
46//! container: Arc<Container>,
47//! // Future additions without breaking changes:
48//! // request_id: RequestId,
49//! // execution_metadata: ExecutionMetadata,
50//! // tracing_context: TracingContext,
51//! // user_permissions: UserPermissions,
52//! }
53//! ```
54//!
55//! ### 2. Clear Abstraction and Intent
56//!
57//! `ExecutionContext` represents "everything a command needs to execute" rather than
58//! exposing dependency injection mechanics directly:
59//!
60//! ```rust,no_run
61//! use torrust_tracker_deployer_lib::bootstrap::Container;
62//! use torrust_tracker_deployer_lib::presentation::cli::dispatch::ExecutionContext;
63//!
64//! # fn example() {
65//! // Clear: This is specifically for command execution
66//! fn handle_command(context: &ExecutionContext) {
67//! // Command execution logic
68//! }
69//!
70//! // Less clear: Could be for bootstrapping, testing, or execution
71//! fn handle_command_old(container: &Container) {
72//! // Generic container usage
73//! }
74//! # }
75//! ```
76//!
77//! ### 3. Command-Specific Service Access
78//!
79//! `ExecutionContext` can provide command-specific convenience methods and service
80//! aggregations without exposing the entire Container interface.
81//!
82//! For the complete rationale, see the architectural decision record:
83//! [`docs/decisions/execution-context-wrapper.md`](../../../docs/decisions/execution-context-wrapper.md)
84//!
85//! ## Design Principles
86//!
87//! - **Route, Don't Execute**: This layer only routes commands, doesn't execute them
88//! - **Dependency Injection**: Provide clean access to services via `ExecutionContext`
89//! - **Type Safety**: Use strongly-typed routing with match statements
90//! - **Error Propagation**: Pass routing errors up to caller
91//!
92//! ## Integration with Presentation Layer
93//!
94//! The Dispatch Layer integrates with the broader presentation layer architecture:
95//!
96//! 1. **Input Layer** (`input/`) - Parses user input into Commands enum
97//! 2. **Dispatch Layer** (this module) - Routes commands and provides context
98//! 3. **Controller Layer** (`commands/`) - Executes command logic with context
99//! 4. **View Layer** (`user_output/`, `progress.rs`) - Presents results to users
100//!
101//! ## Usage Pattern
102//!
103//! ```rust,ignore
104//! use std::path::Path;
105//! use std::sync::Arc;
106//! use torrust_tracker_deployer_lib::bootstrap::Container;
107//! use torrust_tracker_deployer_lib::presentation::cli::dispatch::{route_command, ExecutionContext};
108//! use torrust_tracker_deployer_lib::presentation::cli::views::VerbosityLevel;
109//! // Note: Commands enum requires specific action parameters in practice
110//!
111//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
112//! let container = Container::new(VerbosityLevel::Normal);
113//! let context = ExecutionContext::new(Arc::new(container), global_args);
114//! let working_dir = Path::new(".");
115//!
116//! // Execute a command through the dispatch layer
117//! // Note: route_command is synchronous, not async
118//! // Commands require proper construction with actions
119//! # Ok(())
120//! # }
121//! ```
122
123// Command routing module
124pub mod router;
125
126// Execution context module
127pub mod context;
128
129// Re-export main types for convenience
130pub use context::ExecutionContext;
131pub use router::route_command;