docker_wrapper/command/builder/
use_cmd.rs

1//! Docker buildx use command implementation.
2
3use crate::command::{CommandExecutor, CommandOutput, DockerCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7/// Result of buildx use command
8#[derive(Debug, Clone)]
9pub struct BuildxUseResult {
10    /// The name of the builder that was set
11    pub name: String,
12    /// Raw output from the command
13    pub output: String,
14    /// Whether the command succeeded
15    pub success: bool,
16}
17
18impl BuildxUseResult {
19    /// Parse the buildx use output
20    fn parse(name: &str, output: &CommandOutput) -> Self {
21        Self {
22            name: name.to_string(),
23            output: output.stdout.clone(),
24            success: output.success,
25        }
26    }
27}
28
29/// Docker buildx use command builder
30///
31/// Sets the current builder instance.
32///
33/// # Example
34///
35/// ```rust,no_run
36/// use docker_wrapper::{DockerCommand, BuildxUseCommand};
37///
38/// # #[tokio::main]
39/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
40/// let result = BuildxUseCommand::new("mybuilder")
41///     .default()
42///     .execute()
43///     .await?;
44///
45/// println!("Now using builder: {}", result.name);
46/// # Ok(())
47/// # }
48/// ```
49#[derive(Debug, Clone)]
50pub struct BuildxUseCommand {
51    /// The builder name to use
52    name: String,
53    /// Set builder as default for current context
54    default: bool,
55    /// Builder persists context changes
56    global: bool,
57    /// Command executor
58    pub executor: CommandExecutor,
59}
60
61impl BuildxUseCommand {
62    /// Create a new buildx use command
63    ///
64    /// # Arguments
65    ///
66    /// * `name` - The name of the builder to use
67    #[must_use]
68    pub fn new(name: impl Into<String>) -> Self {
69        Self {
70            name: name.into(),
71            default: false,
72            global: false,
73            executor: CommandExecutor::new(),
74        }
75    }
76
77    /// Set builder as default for current context
78    #[must_use]
79    pub fn default(mut self) -> Self {
80        self.default = true;
81        self
82    }
83
84    /// Builder persists context changes
85    #[must_use]
86    pub fn global(mut self) -> Self {
87        self.global = true;
88        self
89    }
90
91    /// Build the command arguments
92    fn build_args(&self) -> Vec<String> {
93        let mut args = vec!["buildx".to_string(), "use".to_string()];
94
95        if self.default {
96            args.push("--default".to_string());
97        }
98
99        if self.global {
100            args.push("--global".to_string());
101        }
102
103        args.push(self.name.clone());
104
105        args.extend(self.executor.raw_args.clone());
106
107        args
108    }
109}
110
111#[async_trait]
112impl DockerCommand for BuildxUseCommand {
113    type Output = BuildxUseResult;
114
115    fn get_executor(&self) -> &CommandExecutor {
116        &self.executor
117    }
118
119    fn get_executor_mut(&mut self) -> &mut CommandExecutor {
120        &mut self.executor
121    }
122
123    fn build_command_args(&self) -> Vec<String> {
124        self.build_args()
125    }
126
127    async fn execute(&self) -> Result<Self::Output> {
128        let args = self.build_args();
129        let output = self.execute_command(args).await?;
130        Ok(BuildxUseResult::parse(&self.name, &output))
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn test_buildx_use_basic() {
140        let cmd = BuildxUseCommand::new("mybuilder");
141        let args = cmd.build_args();
142        assert_eq!(args, vec!["buildx", "use", "mybuilder"]);
143    }
144
145    #[test]
146    fn test_buildx_use_with_default() {
147        let cmd = BuildxUseCommand::new("mybuilder").default();
148        let args = cmd.build_args();
149        assert!(args.contains(&"--default".to_string()));
150    }
151
152    #[test]
153    fn test_buildx_use_with_global() {
154        let cmd = BuildxUseCommand::new("mybuilder").global();
155        let args = cmd.build_args();
156        assert!(args.contains(&"--global".to_string()));
157    }
158
159    #[test]
160    fn test_buildx_use_all_options() {
161        let cmd = BuildxUseCommand::new("mybuilder").default().global();
162        let args = cmd.build_args();
163        assert!(args.contains(&"--default".to_string()));
164        assert!(args.contains(&"--global".to_string()));
165        assert!(args.contains(&"mybuilder".to_string()));
166    }
167}