adnv 1.5.0

CLI that tracks, checks and auto-updates infrastructure dependency versions across Terraform, Helm, Docker, Git and npm
Documentation
use super::error::Error;
use crate::parsers::hcl::{
    Pair, Rule,
    ast::{Attribute, Block},
};

#[derive(Debug, Clone)]
pub struct Body<'i> {
    pub attributes: Vec<Attribute<'i>>,
    pub blocks: Vec<Block<'i>>,
}

impl<'i> Body<'i> {
    pub fn find_blocks<'s, 'j>(&'s self, id: &'j str) -> impl Iterator<Item = &'s Block<'i>> + 'j
    where
        's: 'j,
    {
        self.blocks.iter().filter(|block| block.id == id)
    }

    pub fn get_block(&self, id: &str, args: Option<&[&str]>) -> Option<&Block<'i>> {
        self.find_blocks(id)
            .find(|block| args.is_none_or(|args| block.args == args))
    }

    pub fn get_attribute(&self, name: &str) -> Option<&Attribute<'i>> {
        self.attributes.iter().find(|attr| attr.name == name)
    }

    pub fn get_attributes_with_inline_hints(&self) -> Vec<&Attribute<'i>> {
        self.attributes
            .iter()
            .filter(|attr| attr.hint.is_some())
            .collect()
    }
}

impl<'i> Body<'i> {
    pub(super) fn process(pair: Pair<'i>) -> (Self, Vec<Error>) {
        let mut attributes = vec![];
        let mut blocks = vec![];
        let mut errors = vec![];

        for item in pair.into_inner() {
            match item.as_rule() {
                Rule::Attribute => match Attribute::process(item) {
                    Ok(processed_item) => attributes.push(processed_item),
                    Err(e) => errors.push(e),
                },
                Rule::AttributeError => {
                    let (l, _) = item.line_col();
                    errors.push(Error::MultipleInlineHint {
                        hint: item.as_str().to_string(),
                        line: l.to_string(),
                    });
                }
                Rule::Block => {
                    let (block, errs) = Block::process(item);
                    blocks.push(block);
                    errors.extend(errs);
                }
                rule => unreachable!("{rule:?}"),
            }
        }

        (Self { attributes, blocks }, errors)
    }
}