use std::fs;
use clap::Parser;
use std::path::Path;
use glob::glob;
mod configuration;
use crate::configuration::{ReplaceConfig, FullReplace, load_configuration};
#[derive(Debug, Parser)]
#[command(version, about)]
struct Args {
#[arg(short = 'i', long = "input")]
input: String,
#[arg(short = 'r', long = "rundir")]
rundir: String,
}
fn replace_file_pattern(file_counter: &mut u64, filename: &Path, vec_replace_config: &Vec<ReplaceConfig>){
println!("replace_file_pattern : ({}) update file '{:?}'", file_counter, filename);
let mut content: String = match fs::read_to_string(filename) {
Ok(str) => str,
Err(err) => panic!("replace_file_pattern : cannot read file '{:?}', error: {}", filename, err)
};
for replace_config in vec_replace_config.iter() {
let tmp = content.replace(&replace_config.pattern, &replace_config.replace);
content = tmp.clone();
}
match fs::write(&filename, &content){
Ok(_) => {},
Err(err) => panic!("replace_file_pattern : cannot write file '{:?}', error: {}", filename, err)
};
*file_counter += 1;
}
fn replace_all(replace_config: &FullReplace, rundir: &String){
let mut file_counter: u64 = 0;
for pattern in replace_config.vec_file_pattern.iter() {
let search_pattern = format!("{}/**/{}", rundir, pattern);
match glob(&search_pattern) {
Ok(fileiter) => for filename in fileiter.into_iter() {
match filename {
Ok(working_file) => replace_file_pattern(&mut file_counter, working_file.as_path(), &replace_config.replace),
Err(err) => println!("Cannot use file, error '{}'", err)
}
},
Err(_) => println!("Pattern '{}' not found", search_pattern)
};
}
}
fn main() {
println!("Replace String");
let args = Args::parse();
let replace_config: FullReplace = match load_configuration(&args.input){
Ok(config) => config,
Err(error) => panic!("{}", error)
};
replace_all(&replace_config, &args.rundir);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_replace_all() {
let output_dir = "generated/";
let textfile = format!("{}/file.txt", output_dir);
fs::create_dir_all(output_dir).unwrap();
fs::write(&textfile, "contents\nto be modified\nand\nother values\n\n").unwrap();
let replace_config: FullReplace = FullReplace{replace: vec![
ReplaceConfig{pattern: String::from("modified\nand"), replace: String::from("changed\nto some")}
], vec_file_pattern: vec![String::from("*.txt")]};
replace_all(&replace_config, &output_dir.to_string());
assert_eq!(fs::read_to_string(&textfile).unwrap(), "contents\nto be changed\nto some\nother values\n\n");
}
}