bat-cli 0.6.6

Blockchain Auditor Toolkit (BAT)
use crate::batbelt::metadata::functions_metadata::FunctionMetadata;
use crate::batbelt::metadata::traits_metadata::TraitMetadata;
use crate::batbelt::parser::ParserError;

use crate::batbelt::metadata::BatMetadataParser;
use error_stack::{Result, ResultExt};
use regex::Regex;

#[derive(Clone, Debug)]
pub struct TraitParser {
    pub name: String,
    pub impl_from: String,
    pub impl_to: String,
    pub trait_metadata: TraitMetadata,
    pub impl_functions: Vec<FunctionMetadata>,
}

impl TraitParser {
    pub fn new_from_metadata(
        trait_metadata: TraitMetadata,
        optional_function_metadata_vec: Option<Vec<FunctionMetadata>>,
    ) -> Result<Self, ParserError> {
        let name = trait_metadata.name.clone();
        let mut new_parser = Self {
            name,
            impl_from: "".to_string(),
            impl_to: "".to_string(),
            trait_metadata,
            impl_functions: vec![],
        };
        log::debug!("new_trait_parser:\n{:#?}", new_parser);
        new_parser.get_impl_function(optional_function_metadata_vec)?;
        new_parser.get_from_to()?;
        Ok(new_parser)
    }

    fn get_impl_function(
        &mut self,
        optional_function_metadata_vec: Option<Vec<FunctionMetadata>>,
    ) -> Result<(), ParserError> {
        let function_metadata_vec = if optional_function_metadata_vec.is_some() {
            optional_function_metadata_vec.unwrap()
        } else {
            FunctionMetadata::get_filtered_metadata(None, None).change_context(ParserError)?
        };
        let filtered_metadata_vec = function_metadata_vec
            .into_iter()
            .filter(|f_metadata| {
                f_metadata.path == self.trait_metadata.path
                    && f_metadata.start_line_index > self.trait_metadata.start_line_index
                    && f_metadata.end_line_index < self.trait_metadata.end_line_index
            })
            .collect::<Vec<_>>();
        self.impl_functions = filtered_metadata_vec;
        Ok(())
    }

    fn get_from_to(&mut self) -> Result<(), ParserError> {
        let name = self.name.clone();
        let match_regex = Regex::new(r"[A-Za-z0-9]+<[<A-Za-z0-9>]+> for [A-Za-z0-9]+").unwrap();
        let _generic_type_regex = Regex::new(r"").unwrap();
        if match_regex.is_match(&name) {
            let mut splitted = name.split(" for ");
            self.impl_from = splitted.next().unwrap().to_string();
            self.impl_to = splitted.next().unwrap().to_string();
        } else {
            self.impl_to = name;
        }
        Ok(())
    }
}