use super::GateFinding;
use std::collections::HashMap;
fn indent_of(line: &str) -> usize {
line.len() - line.trim_start().len()
}
fn is_key_line(trimmed: &str) -> bool {
!trimmed.is_empty() && !trimmed.starts_with('#') && !trimmed.starts_with('-')
}
pub fn resource_line(yaml_text: &str, resource_id: &str) -> Option<usize> {
let lines: Vec<&str> = yaml_text.lines().collect();
let start = lines
.iter()
.position(|l| l.trim_end() == "resources:" && indent_of(l) == 0)?;
let mut child_indent: Option<usize> = None;
for (offset, line) in lines.iter().enumerate().skip(start + 1) {
let trimmed = line.trim();
if !is_key_line(trimmed) {
continue;
}
let indent = indent_of(line);
if indent == 0 {
return None; }
let expected = *child_indent.get_or_insert(indent);
if indent == expected && trimmed.starts_with(&format!("{resource_id}:")) {
return Some(offset + 1);
}
}
None
}
pub fn annotate(yaml_text: &str, findings: &mut [GateFinding]) {
let mut cache: HashMap<String, Option<usize>> = HashMap::new();
for f in findings.iter_mut() {
if f.resource_id.is_empty() {
continue;
}
let line = cache
.entry(f.resource_id.clone())
.or_insert_with(|| resource_line(yaml_text, &f.resource_id));
f.yaml_line = *line;
}
}