torrust_tracker_deployer_lib/application/command_handlers/exists/handler.rs
1//! Exists command handler implementation
2//!
3//! **Purpose**: Check whether an environment exists
4//!
5//! This handler checks whether an environment with the given name exists
6//! in the data directory. It is a read-only operation that does not modify
7//! any state or make any network calls.
8//!
9//! ## Design Rationale
10//!
11//! - "Not found" is a valid result (`exists = false`), NOT an error
12//! - Only repository access failures produce errors
13//! - Returns a simple boolean result via `ExistsResult`
14
15use std::sync::Arc;
16
17use tracing::instrument;
18
19use super::errors::ExistsCommandHandlerError;
20use crate::domain::environment::repository::EnvironmentRepository;
21use crate::domain::EnvironmentName;
22
23/// Result of checking whether an environment exists
24#[derive(Debug, Clone)]
25pub struct ExistsResult {
26 /// The environment name that was checked
27 pub name: String,
28 /// Whether the environment exists
29 pub exists: bool,
30}
31
32/// `ExistsCommandHandler` checks whether an environment exists
33///
34/// **Purpose**: Read-only existence check against the repository
35///
36/// This handler queries the repository to determine if an environment
37/// with the given name exists. It never modifies state or makes network calls.
38pub struct ExistsCommandHandler {
39 repository: Arc<dyn EnvironmentRepository>,
40}
41
42impl ExistsCommandHandler {
43 /// Create a new `ExistsCommandHandler`
44 #[must_use]
45 pub fn new(repository: Arc<dyn EnvironmentRepository>) -> Self {
46 Self { repository }
47 }
48
49 /// Execute the exists command workflow
50 ///
51 /// Checks whether the named environment exists in the repository.
52 ///
53 /// # Arguments
54 ///
55 /// * `env_name` - The name of the environment to check
56 ///
57 /// # Returns
58 ///
59 /// * `Ok(ExistsResult)` - Result indicating whether the environment exists
60 /// * `Err(ExistsCommandHandlerError)` - If the repository check fails
61 ///
62 /// # Errors
63 ///
64 /// Returns an error if:
65 /// * Repository access fails (file system error, permissions, etc.)
66 #[instrument(
67 name = "exists_command",
68 skip_all,
69 fields(
70 command_type = "exists",
71 environment = %env_name
72 )
73 )]
74 pub fn execute(
75 &self,
76 env_name: &EnvironmentName,
77 ) -> Result<ExistsResult, ExistsCommandHandlerError> {
78 let exists = self.repository.exists(env_name)?;
79
80 Ok(ExistsResult {
81 name: env_name.to_string(),
82 exists,
83 })
84 }
85}