-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathrouter.rs
More file actions
223 lines (219 loc) · 7.06 KB
/
Copy pathrouter.rs
File metadata and controls
223 lines (219 loc) · 7.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
//! Command Router
//!
//! This module provides the central command routing functionality for the Dispatch Layer.
//! It contains the `route_command` function that matches parsed CLI commands to their
//! appropriate handler functions.
//!
//! ## Purpose
//!
//! The router extracts command dispatch logic from the main application bootstrap and
//! the presentation commands module, creating a clean separation between:
//!
//! - **Command parsing** (Input Layer - already done)
//! - **Command routing** (This module - routes commands to handlers)
//! - **Command execution** (Controller Layer - executes business logic)
//! - **Result presentation** (View Layer - displays results)
//!
//! ## Design
//!
//! ```text
//! Commands enum → route_command() → Handler function
//! ↓ ↓ ↓
//! Parsed input Route decision Business logic
//! ```
//!
//! ## Benefits
//!
//! - **Centralized Routing**: All command routing logic in one place
//! - **Type Safety**: Compile-time guarantees that all commands are handled
//! - **Testability**: Router can be tested independently of handlers
//! - **Maintainability**: Easy to add new commands or modify routing logic
//!
//! ## Usage Example
//!
//! ```rust,ignore
//! use std::path::Path;
//! use std::sync::Arc;
//! use torrust_tracker_deployer_lib::bootstrap::Container;
//! use torrust_tracker_deployer_lib::presentation::dispatch::{route_command, ExecutionContext};
//! use torrust_tracker_deployer_lib::presentation::views::VerbosityLevel;
//! // Note: Commands enum requires specific action parameters in practice
//!
//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
//! let container = Container::new(VerbosityLevel::Normal);
//! let context = ExecutionContext::new(Arc::new(container));
//! let working_dir = Path::new(".");
//!
//! // Route command to appropriate handler
//! // Note: Commands require proper construction with actions
//! # Ok(())
//! # }
//! ```
use std::path::Path;
use crate::presentation::controllers::create;
use crate::presentation::errors::CommandError;
use crate::presentation::input::Commands;
use super::ExecutionContext;
/// Route a parsed command to its appropriate handler
///
/// This function serves as the central dispatch point for all CLI commands.
/// It takes a parsed command and an execution context, then routes the command
/// to the appropriate handler function in the Controllers layer.
///
/// # Arguments
///
/// * `command` - Parsed command from the Input Layer
/// * `working_dir` - Working directory for command execution
/// * `context` - Execution context providing access to application services
///
/// # Returns
///
/// Returns `Ok(())` on successful command execution, or a `CommandError`
/// if the command fails. The error contains detailed context and actionable
/// troubleshooting information.
///
/// # Errors
///
/// Returns an error if:
/// - Command handler execution fails
/// - Required services are not available in the context
/// - Command parameters are invalid
///
/// # Examples
///
/// ```text
/// use std::path::Path;
/// use std::sync::Arc;
/// use torrust_tracker_deployer_lib::bootstrap::Container;
/// use torrust_tracker_deployer_lib::presentation::dispatch::{route_command, ExecutionContext};
/// use torrust_tracker_deployer_lib::presentation::views::VerbosityLevel;
/// // Note: Commands enum requires specific action parameters in practice
///
/// async fn example() -> Result<(), Box<dyn std::error::Error>> {
/// let container = Container::new(VerbosityLevel::Normal);
/// let context = ExecutionContext::new(Arc::new(container));
/// let working_dir = Path::new(".");
///
/// // Route command to appropriate handler - requires proper Commands construction
/// // route_command(command, working_dir, &context).await?;
/// Ok(())
/// }
/// ```
#[allow(clippy::too_many_lines)]
pub async fn route_command(
command: Commands,
working_dir: &Path,
context: &ExecutionContext,
) -> Result<(), CommandError> {
match command {
Commands::Create { action } => {
create::route_command(action, working_dir, context).await?;
Ok(())
}
Commands::Destroy { environment } => {
context
.container()
.create_destroy_controller()
.execute(&environment)
.await?;
Ok(())
}
Commands::Purge { environment, force } => {
context
.container()
.create_purge_controller()
.execute(&environment, force)
.await?;
Ok(())
}
Commands::Provision { environment } => {
context
.container()
.create_provision_controller()
.execute(&environment)
.await?;
Ok(())
}
Commands::Configure { environment } => {
context
.container()
.create_configure_controller()
.execute(&environment)?;
Ok(())
}
Commands::Test { environment } => {
context
.container()
.create_test_controller()
.execute(&environment)
.await?;
Ok(())
}
Commands::Validate { env_file } => {
context
.container()
.create_validate_controller()
.execute(&env_file)?;
Ok(())
}
Commands::Register {
environment,
instance_ip,
ssh_port,
} => {
context
.container()
.create_register_controller()
.execute(&environment, &instance_ip, ssh_port)
.await?;
Ok(())
}
Commands::Release { environment } => {
context
.container()
.create_release_controller()
.execute(&environment)
.await?;
Ok(())
}
Commands::Render {
env_name,
env_file,
instance_ip,
output_dir,
force,
} => {
context
.container()
.create_render_controller()
.execute(
env_name.as_deref(),
env_file.as_deref(),
&instance_ip,
output_dir.as_path(),
force,
)
.await?;
Ok(())
}
Commands::Run { environment } => {
context
.container()
.create_run_controller()
.execute(&environment)
.await?;
Ok(())
}
Commands::Show { environment } => {
context
.container()
.create_show_controller()
.execute(&environment)?;
Ok(())
}
Commands::List => {
context.container().create_list_controller().execute()?;
Ok(())
}
}
}