docker_wrapper/command/context/
rm.rs1use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
26pub struct ContextRmCommand {
27 contexts: Vec<String>,
29 force: bool,
31 pub executor: CommandExecutor,
33}
34
35impl ContextRmCommand {
36 #[must_use]
38 pub fn new(context: impl Into<String>) -> Self {
39 Self {
40 contexts: vec![context.into()],
41 force: false,
42 executor: CommandExecutor::new(),
43 }
44 }
45
46 #[must_use]
48 pub fn add_context(mut self, context: impl Into<String>) -> Self {
49 self.contexts.push(context.into());
50 self
51 }
52
53 #[must_use]
55 pub fn force(mut self) -> Self {
56 self.force = true;
57 self
58 }
59}
60
61#[async_trait]
62impl DockerCommand for ContextRmCommand {
63 type Output = CommandOutput;
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 let mut args = vec!["context".to_string(), "rm".to_string()];
75
76 if self.force {
77 args.push("--force".to_string());
78 }
79
80 args.extend(self.contexts.clone());
81 args.extend(self.executor.raw_args.clone());
82 args
83 }
84
85 async fn execute(&self) -> Result<Self::Output> {
86 let args = self.build_command_args();
87 self.execute_command(args).await
88 }
89}
90
91impl CommandOutput {
93 #[must_use]
95 pub fn removed_contexts(&self) -> Vec<String> {
96 self.stdout
97 .lines()
98 .filter_map(|line| {
99 if line.is_empty() {
100 None
101 } else {
102 Some(line.trim().to_string())
103 }
104 })
105 .collect()
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_context_rm_single() {
115 let cmd = ContextRmCommand::new("test-context");
116 let args = cmd.build_command_args();
117 assert_eq!(args[0], "context");
118 assert_eq!(args[1], "rm");
119 assert!(args.contains(&"test-context".to_string()));
120 }
121
122 #[test]
123 fn test_context_rm_multiple() {
124 let cmd = ContextRmCommand::new("context1").add_context("context2");
125 let args = cmd.build_command_args();
126 assert!(args.contains(&"context1".to_string()));
127 assert!(args.contains(&"context2".to_string()));
128 }
129
130 #[test]
131 fn test_context_rm_force() {
132 let cmd = ContextRmCommand::new("test-context").force();
133 let args = cmd.build_command_args();
134 assert!(args.contains(&"--force".to_string()));
135 }
136
137 #[test]
138 fn test_removed_contexts_parsing() {
139 let output = CommandOutput {
140 stdout: "context1\ncontext2\n".to_string(),
141 stderr: String::new(),
142 exit_code: 0,
143 success: true,
144 };
145
146 let removed = output.removed_contexts();
147 assert_eq!(removed.len(), 2);
148 assert_eq!(removed[0], "context1");
149 assert_eq!(removed[1], "context2");
150 }
151}