terraform_wrapper/commands/
validate.rs1use crate::Terraform;
2use crate::command::TerraformCommand;
3use crate::error::Result;
4use crate::exec;
5
6#[cfg(feature = "json")]
7use crate::types::validation::ValidationResult;
8
9#[derive(Debug, Clone)]
25pub struct ValidateCommand {
26 json: bool,
27 raw_args: Vec<String>,
28}
29
30impl Default for ValidateCommand {
31 fn default() -> Self {
32 Self {
33 json: true,
34 raw_args: Vec::new(),
35 }
36 }
37}
38
39impl ValidateCommand {
40 #[must_use]
42 pub fn new() -> Self {
43 Self::default()
44 }
45
46 #[must_use]
48 pub fn no_json(mut self) -> Self {
49 self.json = false;
50 self
51 }
52
53 #[must_use]
55 pub fn arg(mut self, arg: impl Into<String>) -> Self {
56 self.raw_args.push(arg.into());
57 self
58 }
59}
60
61#[cfg(feature = "json")]
62impl TerraformCommand for ValidateCommand {
63 type Output = ValidationResult;
64
65 fn args(&self) -> Vec<String> {
66 let mut args = vec!["validate".to_string()];
67 if self.json {
68 args.push("-json".to_string());
69 }
70 args.extend(self.raw_args.clone());
71 args
72 }
73
74 async fn execute(&self, tf: &Terraform) -> Result<ValidationResult> {
75 let output = exec::run_terraform_allow_exit_codes(tf, self.args(), &[0, 1]).await?;
78 serde_json::from_str(&output.stdout).map_err(|e| crate::error::Error::Json {
79 message: "failed to parse validate json".to_string(),
80 source: e,
81 })
82 }
83}
84
85#[cfg(not(feature = "json"))]
86impl TerraformCommand for ValidateCommand {
87 type Output = exec::CommandOutput;
88
89 fn args(&self) -> Vec<String> {
90 let mut args = vec!["validate".to_string()];
91 if self.json {
92 args.push("-json".to_string());
93 }
94 args.extend(self.raw_args.clone());
95 args
96 }
97
98 async fn execute(&self, tf: &Terraform) -> Result<exec::CommandOutput> {
99 exec::run_terraform(tf, self.args()).await
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 fn default_args_include_json() {
109 let cmd = ValidateCommand::new();
110 assert_eq!(cmd.args(), vec!["validate", "-json"]);
111 }
112
113 #[test]
114 fn no_json_args() {
115 let cmd = ValidateCommand::new().no_json();
116 assert_eq!(cmd.args(), vec!["validate"]);
117 }
118
119 #[test]
120 fn raw_arg_escape_hatch() {
121 let cmd = ValidateCommand::new().arg("-test-directory=tests");
122 let args = cmd.args();
123 assert!(args.contains(&"-test-directory=tests".to_string()));
124 }
125}