docker_wrapper/compose/
start.rs1use super::{execute_compose_command, ComposeCommand, ComposeConfig, ComposeOutput};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone, Default)]
9pub struct ComposeStartCommand {
10 config: ComposeConfig,
11 services: Vec<String>,
12}
13
14impl ComposeStartCommand {
15 #[must_use]
17 pub fn new() -> Self {
18 Self::default()
19 }
20
21 #[must_use]
23 pub fn with_config(config: ComposeConfig) -> Self {
24 Self {
25 config,
26 ..Default::default()
27 }
28 }
29
30 #[must_use]
32 pub fn service(mut self, service: impl Into<String>) -> Self {
33 self.services.push(service.into());
34 self
35 }
36
37 pub async fn run(&self) -> Result<ComposeOutput> {
43 self.execute().await
44 }
45}
46
47#[async_trait]
48impl ComposeCommand for ComposeStartCommand {
49 type Output = ComposeOutput;
50
51 fn subcommand(&self) -> &'static str {
52 "start"
53 }
54
55 fn build_args(&self) -> Vec<String> {
56 self.services.clone()
57 }
58
59 async fn execute(&self) -> Result<Self::Output> {
60 execute_compose_command(&self.config, self.subcommand(), self.build_args()).await
61 }
62
63 fn config(&self) -> &ComposeConfig {
64 &self.config
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_compose_start_basic() {
74 let cmd = ComposeStartCommand::new();
75 assert_eq!(cmd.subcommand(), "start");
76 assert_eq!(cmd.build_args(), Vec::<String>::new());
77 }
78
79 #[test]
80 fn test_compose_start_with_services() {
81 let cmd = ComposeStartCommand::new()
82 .service("web")
83 .service("db")
84 .service("cache");
85
86 let args = cmd.build_args();
87 assert_eq!(args, vec!["web", "db", "cache"]);
88 }
89
90 #[test]
91 fn test_compose_start_with_config() {
92 let config = ComposeConfig::new()
93 .file("docker-compose.yml")
94 .project_name("myapp")
95 .profile("production");
96
97 let cmd = ComposeStartCommand::with_config(config).service("api");
98
99 assert_eq!(cmd.config().project_name, Some("myapp".to_string()));
100 assert_eq!(cmd.config().profiles, vec!["production"]);
101 assert_eq!(cmd.build_args(), vec!["api"]);
102 }
103
104 #[test]
105 fn test_compose_start_single_service() {
106 let cmd = ComposeStartCommand::new().service("postgres");
107
108 let args = cmd.build_args();
109 assert_eq!(args, vec!["postgres"]);
110 }
111
112 #[test]
113 fn test_compose_start_no_services() {
114 let cmd = ComposeStartCommand::new();
116
117 let args = cmd.build_args();
118 assert!(args.is_empty());
119 }
120
121 #[test]
122 fn test_compose_start_builder_pattern() {
123 let cmd = ComposeStartCommand::with_config(ComposeConfig::new().project_name("test"))
124 .service("frontend")
125 .service("backend");
126
127 assert_eq!(cmd.services.len(), 2);
128 assert!(cmd.services.contains(&"frontend".to_string()));
129 assert!(cmd.services.contains(&"backend".to_string()));
130 }
131}