docker_wrapper/command/swarm/
leave.rs1use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub struct SwarmLeaveResult {
10 pub success: bool,
12 pub output: String,
14}
15
16impl SwarmLeaveResult {
17 fn parse(output: &CommandOutput) -> Self {
19 Self {
20 success: output.success,
21 output: output.stdout.clone(),
22 }
23 }
24}
25
26#[derive(Debug, Clone, Default)]
28pub struct SwarmLeaveCommand {
29 force: bool,
31 pub executor: CommandExecutor,
33}
34
35impl SwarmLeaveCommand {
36 #[must_use]
38 pub fn new() -> Self {
39 Self::default()
40 }
41
42 #[must_use]
44 pub fn force(mut self) -> Self {
45 self.force = true;
46 self
47 }
48
49 fn build_args(&self) -> Vec<String> {
51 let mut args = vec!["swarm".to_string(), "leave".to_string()];
52
53 if self.force {
54 args.push("--force".to_string());
55 }
56
57 args
58 }
59}
60
61#[async_trait]
62impl DockerCommand for SwarmLeaveCommand {
63 type Output = SwarmLeaveResult;
64
65 fn get_executor(&self) -> &CommandExecutor {
66 &self.executor
67 }
68
69 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
70 &mut self.executor
71 }
72
73 fn build_command_args(&self) -> Vec<String> {
74 self.build_args()
75 }
76
77 async fn execute(&self) -> Result<Self::Output> {
78 let args = self.build_args();
79 let output = self.execute_command(args).await?;
80 Ok(SwarmLeaveResult::parse(&output))
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_swarm_leave_basic() {
90 let cmd = SwarmLeaveCommand::new();
91 let args = cmd.build_args();
92 assert_eq!(args, vec!["swarm", "leave"]);
93 }
94
95 #[test]
96 fn test_swarm_leave_force() {
97 let cmd = SwarmLeaveCommand::new().force();
98 let args = cmd.build_args();
99 assert!(args.contains(&"--force".to_string()));
100 }
101}