mock_gen 0.1.22

Interface and mock generator for C++ classes
#![allow(unused)]

use crate::args::{ApiMockCmd, Commands, InterfaceCmd, MockCmd, MockGen};
use crate::prelude::*;
use crate::utils::gen_interface::*;
use crate::utils::gen_mock::*;
use crate::utils::parse_func::*;
mod args;
mod error;
mod prelude;
mod utils;

use clap::{Args, Command, Parser};
use walkdir::{DirEntry, WalkDir};

fn generate_interface(cmds: InterfaceCmd) -> Result<()> {
    let class_string = find_class_substring(cmds.file.as_str(), cmds.class.as_str()).unwrap();
    let functions = find_function_names(&class_string).unwrap();
    replace_line(functions, &cmds.file, &cmds.class).unwrap();
    Ok(())
}

fn generate_mock(cmds: MockCmd) -> Result<()> {
    let class_string = find_class_substring(cmds.file.as_str(), cmds.class.as_str()).unwrap();
    let mut functions = find_function_names(&class_string).unwrap();

    let output = match cmds.output {
        Some(x) => x,
        _ => ".".to_string(),
    };
    let mut objects: Vec<&str> = cmds.class.as_str().split("_").collect();
    objects.pop();
    objects.push("interface");
    let interface_name = ": public ".to_owned() + objects.join("_").as_str();

    generate_mock_file(
        &output,
        cmds.file.as_str(),
        cmds.class.as_str(),
        interface_name.as_str(),
        &mut functions,
    )?;
    Ok(())
}

fn generate_cmock(cmds: ApiMockCmd) -> Result<()> {
    //find all class strings
    let mut functions = find_c_function_names(cmds.file.as_str()).unwrap();

    //if output specified use it or just go to working dir
    let output = match cmds.output {
        Some(x) => x,
        _ => ".".to_string(),
    };
    generate_cmock_file(&output, &cmds.file, &mut functions)?;
    Ok(())
}

fn find_file_path(file_name: &str) -> Result<String> {
    let path = std::env::current_dir().unwrap();
    dbg!(&path);
    let walker = WalkDir::new(path).into_iter();
    for entry in walker {
        let entry = entry.unwrap();
        let string_path = entry.path().to_str().to_owned().unwrap();
        if string_path.contains(file_name) {
            let file_result: Result<&str> = match string_path.rsplit_once("\\") {
                Some(val) => Ok(val.1),
                _ => continue,
            };
            let file_path = file_result.unwrap();

            match file_path {
                _ if file_path == file_name => return Ok(string_path.to_owned()),
                _ => continue,
            };
        }
    }
    Err(Error::Generic(
        format!("error: {file_name} no found").to_owned(),
    ))
}

fn main() -> Result<()> {
    let mut args = MockGen::parse();

    match args.commands {
        Commands::Interface(mut command) => {
            println!(
                "generating interface for class:{} in file: {}",
                command.class, command.file
            );
            command.file = find_file_path(&command.file)?;
            generate_interface(command);
        }
        Commands::Mock(mut command) => {
            println!(
                "generating mock of class:{} from file:{}",
                command.class, command.file
            );
            command.file = find_file_path(&command.file)?;
            generate_mock(command);
        }
        Commands::ApiMock(mut command) => {
            println!("generating c mock of from file:{}", command.file);
            command.file = find_file_path(&command.file)?;
            generate_cmock(command);
        }
        Commands::IMock(mut command) => {
            println!(
                "generating interface and mock of {} from file:{}",
                command.class, command.file
            );
            command.file = find_file_path(&command.file)?;

            let interface_cmd = InterfaceCmd {
                file: command.file.clone(),
                class: command.class.clone(),
            };

            let mock_cmd = MockCmd {
                file: command.file.clone(),
                class: command.class.clone(),
                output: command.output.clone(),
            };

            generate_interface(interface_cmd);
            generate_mock(mock_cmd);
        }
        _ => println!("{}", String::from("no arguments")),
    };
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::utils::gen_mock::*;
    #[test]
    fn test_mock_gen() {
        dbg!(generate_mock_string(
            "uint16& set_calibration_status(bool value, float32 test, int16_t why)"
        ));
    }
}