docker_wrapper/command/compose/
convert.rs1use crate::command::{CommandExecutor, ComposeCommand, ComposeConfig, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub struct ComposeConvertCommand {
10 pub executor: CommandExecutor,
12 pub config: ComposeConfig,
14 pub format: Option<ConvertFormat>,
16 pub output: Option<String>,
18}
19
20#[derive(Debug, Clone, Copy)]
22pub enum ConvertFormat {
23 Yaml,
25 Json,
27}
28
29impl std::fmt::Display for ConvertFormat {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 Self::Yaml => write!(f, "yaml"),
33 Self::Json => write!(f, "json"),
34 }
35 }
36}
37
38#[derive(Debug, Clone)]
40pub struct ComposeConvertResult {
41 pub stdout: String,
43 pub stderr: String,
45 pub success: bool,
47 pub converted_config: String,
49}
50
51impl ComposeConvertCommand {
52 #[must_use]
54 pub fn new() -> Self {
55 Self {
56 executor: CommandExecutor::new(),
57 config: ComposeConfig::new(),
58 format: None,
59 output: None,
60 }
61 }
62
63 #[must_use]
65 pub fn format(mut self, format: ConvertFormat) -> Self {
66 self.format = Some(format);
67 self
68 }
69
70 #[must_use]
72 pub fn format_json(mut self) -> Self {
73 self.format = Some(ConvertFormat::Json);
74 self
75 }
76
77 #[must_use]
79 pub fn format_yaml(mut self) -> Self {
80 self.format = Some(ConvertFormat::Yaml);
81 self
82 }
83
84 #[must_use]
86 pub fn output(mut self, output: impl Into<String>) -> Self {
87 self.output = Some(output.into());
88 self
89 }
90}
91
92impl Default for ComposeConvertCommand {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98#[async_trait]
99impl DockerCommand for ComposeConvertCommand {
100 type Output = ComposeConvertResult;
101
102 fn get_executor(&self) -> &CommandExecutor {
103 &self.executor
104 }
105
106 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
107 &mut self.executor
108 }
109
110 fn build_command_args(&self) -> Vec<String> {
111 <Self as ComposeCommand>::build_command_args(self)
112 }
113
114 async fn execute(&self) -> Result<Self::Output> {
115 let args = <Self as ComposeCommand>::build_command_args(self);
116 let output = self.execute_command(args).await?;
117
118 Ok(ComposeConvertResult {
119 stdout: output.stdout.clone(),
120 stderr: output.stderr,
121 success: output.success,
122 converted_config: output.stdout,
123 })
124 }
125}
126
127impl ComposeCommand for ComposeConvertCommand {
128 fn get_config(&self) -> &ComposeConfig {
129 &self.config
130 }
131
132 fn get_config_mut(&mut self) -> &mut ComposeConfig {
133 &mut self.config
134 }
135
136 fn subcommand(&self) -> &'static str {
137 "convert"
138 }
139
140 fn build_subcommand_args(&self) -> Vec<String> {
141 let mut args = Vec::new();
142
143 if let Some(format) = self.format {
144 args.push("--format".to_string());
145 args.push(format.to_string());
146 }
147
148 if let Some(ref output) = self.output {
149 args.push("--output".to_string());
150 args.push(output.clone());
151 }
152
153 args
154 }
155}
156
157impl ComposeConvertResult {
158 #[must_use]
160 pub fn success(&self) -> bool {
161 self.success
162 }
163
164 #[must_use]
166 pub fn converted_config(&self) -> &str {
167 &self.converted_config
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 #[test]
176 fn test_compose_convert_basic() {
177 let cmd = ComposeConvertCommand::new();
178 let args = cmd.build_subcommand_args();
179 assert!(args.is_empty());
180
181 let full_args = ComposeCommand::build_command_args(&cmd);
182 assert_eq!(full_args[0], "compose");
183 assert!(full_args.contains(&"convert".to_string()));
184 }
185
186 #[test]
187 fn test_compose_convert_with_format() {
188 let cmd = ComposeConvertCommand::new().format_json();
189 let args = cmd.build_subcommand_args();
190 assert!(args.contains(&"--format".to_string()));
191 assert!(args.contains(&"json".to_string()));
192 }
193
194 #[test]
195 fn test_compose_convert_with_output() {
196 let cmd = ComposeConvertCommand::new().output("output.yml");
197 let args = cmd.build_subcommand_args();
198 assert!(args.contains(&"--output".to_string()));
199 assert!(args.contains(&"output.yml".to_string()));
200 }
201}