cfn_guard/commands/
parse_tree.rs1use crate::commands::{Executable, PRINT_JSON, PRINT_YAML, SUCCESS_STATUS_CODE};
2use crate::rules::Result;
3use crate::utils::reader::Reader;
4use crate::utils::writer::Writer;
5use clap::Args;
6use std::fs::File;
7
8const ABOUT: &str = "Prints out the parse tree for the rules defined in the file.";
9const OUTPUT_HELP: &str = "Write to output file";
10const PRINT_JSON_HELP: &str = "Print output in JSON format. Use -p as the short flag";
11const PRINT_YAML_HELP: &str = "Print output in YAML format";
12const RULES_HELP: &str = "Provide a rules file";
13
14#[derive(Debug, Clone, Eq, PartialEq, Args)]
15#[clap(about=ABOUT)]
16#[clap(arg_required_else_help = true)]
17pub struct ParseTree {
20 #[arg(short, long, help=RULES_HELP)]
24 pub(crate) rules: Option<String>,
25 #[arg(short, long, help=OUTPUT_HELP)]
26 pub(crate) output: Option<String>,
29 #[arg(short=PRINT_JSON.1, long=PRINT_JSON.0, help=PRINT_JSON_HELP)]
32 pub(crate) print_json: bool,
33 #[arg(short=PRINT_YAML.1, long=PRINT_YAML.0, help=PRINT_YAML_HELP)]
36 pub(crate) print_yaml: bool,
37}
38
39impl Executable for ParseTree {
40 fn execute(&self, writer: &mut Writer, reader: &mut Reader) -> Result<i32> {
47 let mut file: Box<dyn std::io::Read> = match &self.rules {
48 Some(file) => Box::new(std::io::BufReader::new(File::open(file)?)),
49 None => Box::new(reader),
50 };
51
52 let mut content = String::new();
53 file.read_to_string(&mut content)?;
54 let span = crate::rules::parser::Span::new_extra(&content, "");
55
56 let rules = crate::rules::parser::rules_file(span)?;
57
58 match self.print_json {
59 true => serde_json::to_writer_pretty(writer, &rules)?,
60 false => serde_yaml::to_writer(writer, &rules)?,
61 }
62
63 Ok(SUCCESS_STATUS_CODE)
64 }
65}