docker_wrapper/command/compose/
top.rs1use crate::command::{CommandExecutor, ComposeCommand, ComposeConfig, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub struct ComposeTopCommand {
10 pub executor: CommandExecutor,
12 pub config: ComposeConfig,
14 pub services: Vec<String>,
16}
17
18#[derive(Debug, Clone)]
20pub struct ComposeTopResult {
21 pub stdout: String,
23 pub stderr: String,
25 pub success: bool,
27 pub services: Vec<String>,
29}
30
31impl ComposeTopCommand {
32 #[must_use]
34 pub fn new() -> Self {
35 Self {
36 executor: CommandExecutor::new(),
37 config: ComposeConfig::new(),
38 services: Vec::new(),
39 }
40 }
41
42 #[must_use]
44 pub fn service(mut self, service: impl Into<String>) -> Self {
45 self.services.push(service.into());
46 self
47 }
48
49 #[must_use]
51 pub fn services<I, S>(mut self, services: I) -> Self
52 where
53 I: IntoIterator<Item = S>,
54 S: Into<String>,
55 {
56 self.services.extend(services.into_iter().map(Into::into));
57 self
58 }
59}
60
61impl Default for ComposeTopCommand {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67#[async_trait]
68impl DockerCommand for ComposeTopCommand {
69 type Output = ComposeTopResult;
70
71 fn get_executor(&self) -> &CommandExecutor {
72 &self.executor
73 }
74
75 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
76 &mut self.executor
77 }
78
79 fn build_command_args(&self) -> Vec<String> {
80 <Self as ComposeCommand>::build_command_args(self)
81 }
82
83 async fn execute(&self) -> Result<Self::Output> {
84 let args = <Self as ComposeCommand>::build_command_args(self);
85 let output = self.execute_command(args).await?;
86
87 Ok(ComposeTopResult {
88 stdout: output.stdout,
89 stderr: output.stderr,
90 success: output.success,
91 services: self.services.clone(),
92 })
93 }
94}
95
96impl ComposeCommand for ComposeTopCommand {
97 fn get_config(&self) -> &ComposeConfig {
98 &self.config
99 }
100
101 fn get_config_mut(&mut self) -> &mut ComposeConfig {
102 &mut self.config
103 }
104
105 fn subcommand(&self) -> &'static str {
106 "top"
107 }
108
109 fn build_subcommand_args(&self) -> Vec<String> {
110 self.services.clone()
111 }
112}
113
114impl ComposeTopResult {
115 #[must_use]
117 pub fn success(&self) -> bool {
118 self.success
119 }
120
121 #[must_use]
123 pub fn services(&self) -> &[String] {
124 &self.services
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_compose_top_basic() {
134 let cmd = ComposeTopCommand::new();
135 let args = cmd.build_subcommand_args();
136 assert!(args.is_empty());
137
138 let full_args = ComposeCommand::build_command_args(&cmd);
139 assert_eq!(full_args[0], "compose");
140 assert!(full_args.contains(&"top".to_string()));
141 }
142
143 #[test]
144 fn test_compose_top_with_services() {
145 let cmd = ComposeTopCommand::new().services(vec!["web", "db"]);
146 let args = cmd.build_subcommand_args();
147 assert_eq!(args, vec!["web", "db"]);
148 }
149}