docker_wrapper/compose/
restart.rs

1//! Docker Compose restart command implementation.
2
3use super::{execute_compose_command, ComposeCommand, ComposeConfig, ComposeOutput};
4use crate::error::Result;
5use async_trait::async_trait;
6use std::time::Duration;
7
8/// Docker Compose restart command builder
9#[derive(Debug, Clone, Default)]
10pub struct ComposeRestartCommand {
11    config: ComposeConfig,
12    services: Vec<String>,
13    timeout: Option<Duration>,
14}
15
16impl ComposeRestartCommand {
17    /// Create a new compose restart command
18    #[must_use]
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    /// Create with a specific configuration
24    #[must_use]
25    pub fn with_config(config: ComposeConfig) -> Self {
26        Self {
27            config,
28            ..Default::default()
29        }
30    }
31
32    /// Add a service to restart
33    #[must_use]
34    pub fn service(mut self, service: impl Into<String>) -> Self {
35        self.services.push(service.into());
36        self
37    }
38
39    /// Set the timeout for stopping containers
40    #[must_use]
41    pub fn timeout(mut self, timeout: Duration) -> Self {
42        self.timeout = Some(timeout);
43        self
44    }
45
46    /// Execute the restart command
47    ///
48    /// # Errors
49    ///
50    /// Returns an error if the docker compose restart command fails
51    pub async fn run(&self) -> Result<ComposeOutput> {
52        self.execute().await
53    }
54}
55
56#[async_trait]
57impl ComposeCommand for ComposeRestartCommand {
58    type Output = ComposeOutput;
59
60    fn subcommand(&self) -> &'static str {
61        "restart"
62    }
63
64    fn build_args(&self) -> Vec<String> {
65        let mut args = Vec::new();
66        if let Some(timeout) = self.timeout {
67            args.push("--timeout".to_string());
68            args.push(timeout.as_secs().to_string());
69        }
70        args.extend(self.services.clone());
71        args
72    }
73
74    async fn execute(&self) -> Result<Self::Output> {
75        execute_compose_command(&self.config, self.subcommand(), self.build_args()).await
76    }
77
78    fn config(&self) -> &ComposeConfig {
79        &self.config
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn test_compose_restart_basic() {
89        let cmd = ComposeRestartCommand::new();
90        assert_eq!(cmd.subcommand(), "restart");
91        assert_eq!(cmd.build_args(), Vec::<String>::new());
92    }
93
94    #[test]
95    fn test_compose_restart_with_services() {
96        let cmd = ComposeRestartCommand::new().service("web").service("db");
97
98        let args = cmd.build_args();
99        assert_eq!(args, vec!["web", "db"]);
100    }
101
102    #[test]
103    fn test_compose_restart_with_timeout() {
104        let cmd = ComposeRestartCommand::new()
105            .timeout(Duration::from_secs(30))
106            .service("app");
107
108        let args = cmd.build_args();
109        assert_eq!(args, vec!["--timeout", "30", "app"]);
110    }
111
112    #[test]
113    fn test_compose_restart_with_config() {
114        let config = ComposeConfig::new()
115            .file("docker-compose.yml")
116            .project_name("myapp");
117
118        let cmd = ComposeRestartCommand::with_config(config)
119            .service("web")
120            .timeout(Duration::from_secs(10));
121
122        assert_eq!(cmd.config().project_name, Some("myapp".to_string()));
123        let args = cmd.build_args();
124        assert_eq!(args, vec!["--timeout", "10", "web"]);
125    }
126
127    #[test]
128    fn test_compose_restart_builder_pattern() {
129        let cmd = ComposeRestartCommand::new()
130            .service("service1")
131            .service("service2")
132            .service("service3")
133            .timeout(Duration::from_secs(60));
134
135        let args = cmd.build_args();
136        assert_eq!(
137            args,
138            vec!["--timeout", "60", "service1", "service2", "service3"]
139        );
140    }
141
142    #[test]
143    fn test_compose_restart_no_timeout() {
144        let cmd = ComposeRestartCommand::new().service("nginx");
145
146        let args = cmd.build_args();
147        assert_eq!(args, vec!["nginx"]);
148    }
149}