terraform_wrapper/commands/
state.rs1use crate::Terraform;
2use crate::command::TerraformCommand;
3use crate::error::Result;
4use crate::exec::{self, CommandOutput};
5
6#[derive(Debug, Clone)]
8pub enum StateSubcommand {
9 List,
11 Show(String),
13 Mv {
15 source: String,
17 destination: String,
19 },
20 Rm(Vec<String>),
22 Pull,
24 Push,
26}
27
28#[derive(Debug, Clone)]
48pub struct StateCommand {
49 subcommand: StateSubcommand,
50 raw_args: Vec<String>,
51}
52
53impl StateCommand {
54 #[must_use]
56 pub fn list() -> Self {
57 Self {
58 subcommand: StateSubcommand::List,
59 raw_args: Vec::new(),
60 }
61 }
62
63 #[must_use]
65 pub fn show(address: &str) -> Self {
66 Self {
67 subcommand: StateSubcommand::Show(address.to_string()),
68 raw_args: Vec::new(),
69 }
70 }
71
72 #[must_use]
74 pub fn mv(source: &str, destination: &str) -> Self {
75 Self {
76 subcommand: StateSubcommand::Mv {
77 source: source.to_string(),
78 destination: destination.to_string(),
79 },
80 raw_args: Vec::new(),
81 }
82 }
83
84 #[must_use]
86 pub fn rm(addresses: Vec<String>) -> Self {
87 Self {
88 subcommand: StateSubcommand::Rm(addresses),
89 raw_args: Vec::new(),
90 }
91 }
92
93 #[must_use]
95 pub fn pull() -> Self {
96 Self {
97 subcommand: StateSubcommand::Pull,
98 raw_args: Vec::new(),
99 }
100 }
101
102 #[must_use]
104 pub fn push() -> Self {
105 Self {
106 subcommand: StateSubcommand::Push,
107 raw_args: Vec::new(),
108 }
109 }
110
111 #[must_use]
113 pub fn arg(mut self, arg: impl Into<String>) -> Self {
114 self.raw_args.push(arg.into());
115 self
116 }
117}
118
119impl TerraformCommand for StateCommand {
120 type Output = CommandOutput;
121
122 fn args(&self) -> Vec<String> {
123 let mut args = vec!["state".to_string()];
124 match &self.subcommand {
125 StateSubcommand::List => args.push("list".to_string()),
126 StateSubcommand::Show(address) => {
127 args.push("show".to_string());
128 args.push(address.clone());
129 }
130 StateSubcommand::Mv {
131 source,
132 destination,
133 } => {
134 args.push("mv".to_string());
135 args.push(source.clone());
136 args.push(destination.clone());
137 }
138 StateSubcommand::Rm(addresses) => {
139 args.push("rm".to_string());
140 args.extend(addresses.clone());
141 }
142 StateSubcommand::Pull => args.push("pull".to_string()),
143 StateSubcommand::Push => args.push("push".to_string()),
144 }
145 args.extend(self.raw_args.clone());
146 args
147 }
148
149 async fn execute(&self, tf: &Terraform) -> Result<CommandOutput> {
150 exec::run_terraform(tf, self.args()).await
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157
158 #[test]
159 fn list_args() {
160 let cmd = StateCommand::list();
161 assert_eq!(cmd.args(), vec!["state", "list"]);
162 }
163
164 #[test]
165 fn show_args() {
166 let cmd = StateCommand::show("null_resource.example");
167 assert_eq!(cmd.args(), vec!["state", "show", "null_resource.example"]);
168 }
169
170 #[test]
171 fn mv_args() {
172 let cmd = StateCommand::mv("null_resource.old", "null_resource.new");
173 assert_eq!(
174 cmd.args(),
175 vec!["state", "mv", "null_resource.old", "null_resource.new"]
176 );
177 }
178
179 #[test]
180 fn rm_args() {
181 let cmd = StateCommand::rm(vec![
182 "null_resource.a".to_string(),
183 "null_resource.b".to_string(),
184 ]);
185 assert_eq!(
186 cmd.args(),
187 vec!["state", "rm", "null_resource.a", "null_resource.b"]
188 );
189 }
190
191 #[test]
192 fn pull_args() {
193 let cmd = StateCommand::pull();
194 assert_eq!(cmd.args(), vec!["state", "pull"]);
195 }
196
197 #[test]
198 fn push_args() {
199 let cmd = StateCommand::push();
200 assert_eq!(cmd.args(), vec!["state", "push"]);
201 }
202}