use lazy_static::lazy_static;
use regex::Regex;
use std::{
collections::HashMap,
fs::{self, File},
io::{BufRead, BufReader, Result, Write},
path::Path,
};
lazy_static! {
static ref REG: HashMap<&'static str, Regex> = {
let mut reg_map = HashMap::new();
reg_map.insert(
"extension_re",
Regex::new(r"\.(.+)$").expect("No valid match"),
);
reg_map.insert(
"line_re",
Regex::new(r"////(.+)$").expect("No matched line"),
);
reg_map
};
}
fn get_new_file_name(filename: &str, extension: &str) -> String {
let filename = Path::new(filename).file_name().unwrap();
let filename: String = filename
.to_str()
.unwrap()
.to_string()
.chars()
.rev()
.collect();
let filename: String = format!(
"{}.{}",
if let Some(val) = REG.get("extension_re").unwrap().captures(&filename) {
val[1].chars().rev().collect()
} else {
"rs".to_owned()
},
extension
);
filename
}
pub fn write_file(
filename: &str,
extension: &str,
map: HashMap<String, Vec<String>>,
) -> Result<()> {
if !map.keys().any(|x| x == &extension.to_string()) {
println!(
"File Extension provided [.{}], has no corresponding write up in the file been used.",
&extension
);
std::process::exit(-1);
}
fs::remove_file(filename)?;
let filename = get_new_file_name(filename, extension);
let mut file = File::create(filename).unwrap();
if map.contains_key(extension) {
for line in map.get(extension).unwrap() {
if REG.get("line_re").unwrap().is_match(line) {
let line = REG.get("line_re").unwrap().captures(&line).unwrap();
if line[1].starts_with("start") {
writeln!(file, "{}", &line[0])?; } else {
writeln!(file, "{}", &line[1])?; }
} else {
writeln!(file, "{}", line)?;
}
}
}
for key in map
.keys()
.filter(|a| **a != extension.to_string())
.collect::<Vec<_>>()
{
for line in map.get(key).unwrap() {
if line.starts_with("////") || line.contains("////") {
writeln!(file, "{}", line)?;
} else {
writeln!(file, "////{}", line)?;
}
}
}
Ok(())
}
pub fn read_file(filename: &str) -> Result<HashMap<String, Vec<String>>> {
let mut map: HashMap<String, Vec<String>> = HashMap::new();
let file = File::open(filename.to_owned())?;
let buf = BufReader::new(file);
let mut key = String::with_capacity(10);
let mut store = vec![];
for line in buf.lines() {
let line = line?;
if line.trim().starts_with("////start") {
let keys = line.split_whitespace().into_iter().collect::<Vec<_>>();
key = keys[1].to_string();
key.shrink_to_fit();
store = vec![line.clone()];
} else {
store.push(line.clone());
}
map.insert(key.clone(), store.clone());
}
map.insert(key, store);
Ok(map)
}
#[cfg(test)]
mod tests;