docker_wrapper/command/network/
disconnect.rs1use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub struct NetworkDisconnectCommand {
10 network: String,
12 container: String,
14 force: bool,
16 pub executor: CommandExecutor,
18}
19
20impl NetworkDisconnectCommand {
21 #[must_use]
23 pub fn new(network: impl Into<String>, container: impl Into<String>) -> Self {
24 Self {
25 network: network.into(),
26 container: container.into(),
27 force: false,
28 executor: CommandExecutor::new(),
29 }
30 }
31
32 #[must_use]
34 pub fn force(mut self) -> Self {
35 self.force = true;
36 self
37 }
38
39 pub async fn run(&self) -> Result<NetworkDisconnectResult> {
45 self.execute().await.map(NetworkDisconnectResult::from)
46 }
47}
48
49#[async_trait]
50impl DockerCommand for NetworkDisconnectCommand {
51 type Output = CommandOutput;
52
53 fn build_command_args(&self) -> Vec<String> {
54 let mut args = vec!["network".to_string(), "disconnect".to_string()];
55
56 if self.force {
57 args.push("--force".to_string());
58 }
59
60 args.push(self.network.clone());
61 args.push(self.container.clone());
62 args.extend(self.executor.raw_args.clone());
63 args
64 }
65
66 fn get_executor(&self) -> &CommandExecutor {
67 &self.executor
68 }
69
70 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
71 &mut self.executor
72 }
73
74 async fn execute(&self) -> Result<Self::Output> {
75 let args = self.build_command_args();
76 let command_name = args[0].clone();
77 let command_args = args[1..].to_vec();
78 self.executor
79 .execute_command(&command_name, command_args)
80 .await
81 }
82}
83
84#[derive(Debug, Clone)]
86pub struct NetworkDisconnectResult {
87 pub raw_output: CommandOutput,
89}
90
91impl From<CommandOutput> for NetworkDisconnectResult {
92 fn from(output: CommandOutput) -> Self {
93 Self { raw_output: output }
94 }
95}
96
97impl NetworkDisconnectResult {
98 #[must_use]
100 pub fn is_success(&self) -> bool {
101 self.raw_output.success
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_network_disconnect_basic() {
111 let cmd = NetworkDisconnectCommand::new("my-network", "my-container");
112 let args = cmd.build_command_args();
113 assert_eq!(
114 args,
115 vec!["network", "disconnect", "my-network", "my-container"]
116 );
117 }
118
119 #[test]
120 fn test_network_disconnect_force() {
121 let cmd = NetworkDisconnectCommand::new("my-network", "my-container").force();
122 let args = cmd.build_command_args();
123 assert_eq!(
124 args,
125 vec![
126 "network",
127 "disconnect",
128 "--force",
129 "my-network",
130 "my-container"
131 ]
132 );
133 }
134}