fn report()

in guard/src/commands/validate/cfn_reporter.rs [48:106]


    fn report(&self,
              writer: &mut dyn Write,
              _status: Option<Status>,
              failed_rules: &[&StatusContext],
              passed_or_skipped: &[&StatusContext],
              longest_rule_name: usize) -> crate::rules::Result<()> {
        let failed = if !failed_rules.is_empty() {
            let mut by_resource_name = HashMap::new();
            for (idx, each_failed_rule) in failed_rules.iter().enumerate() {
                let failed = find_all_failing_clauses(each_failed_rule);
                for (clause_idx, each_failing_clause) in failed.iter().enumerate() {
                    match each_failing_clause.eval_type {
                        EvaluationType::Clause |
                        EvaluationType::BlockClause => {
                            if each_failing_clause.eval_type == EvaluationType::BlockClause {
                                match &each_failing_clause.msg {
                                    Some(msg) => {
                                        if msg.contains("DEFAULT") {
                                            continue;
                                        }
                                    },

                                    None => {
                                        continue;
                                    }
                                }
                            }
                            let mut resource_info = super::common::extract_name_info(
                                &each_failed_rule.context, each_failing_clause)?;
                            let (resource_name, property_path) = match CFN_RESOURCES.captures(&resource_info.path) {
                                Some(caps) => {
                                    (caps["name"].to_string(), caps["rest"].replace("/", "."))
                                },
                                None =>
                                    (format!("Rule {} Resource {} {}", each_failed_rule.context, idx, clause_idx), "".to_string())

                            };
                            resource_info.path = property_path;
                            by_resource_name.entry(resource_name).or_insert(Vec::new()).push(resource_info);
                        },

                        _ => unreachable!()
                    }
                }
            }
            by_resource_name
        } else { HashMap::new() };
        let as_vec = passed_or_skipped.iter().map(|s| *s)
            .collect::<Vec<&StatusContext>>();
        let (skipped, passed): (Vec<&StatusContext>, Vec<&StatusContext>) = as_vec.iter()
            .partition(|status| match status.status { // This uses the dereference deep trait of Rust
                Some(Status::SKIP) => true,
                _ => false
            });
        let skipped = skipped.iter().map(|s| s.context.clone()).collect::<HashSet<String>>();
        let passed = passed.iter().map(|s| s.context.clone()).collect::<HashSet<String>>();
        self.render.report(writer, self.rules_file_name, self.data_file_name, failed, passed, skipped, longest_rule_name)?;
        Ok(())
    }