use std::fs::OpenOptions;
use std::io::prelude::*;
use std::io::{BufRead, BufReader, Write};
use crate::prelude::*;
use crate::utils::parse_func::*;
static FORMAT_OFF: &str = "// clang-format off";
static FORMAT_ON: &str = "// clang-format on";
static GEN_STRING_START: &str = "/* generated interface code */";
static GEN_STRING_END: &str = "/* generated interface code end */";
pub fn remove_generated(lines: &mut Vec<String>) -> Result<&mut Vec<String>> {
for i in 0..lines.len() {
if lines[i].contains(&GEN_STRING_START) {
let mut max_count = lines.len() - i;
lines.remove(i);
loop {
if lines[i].contains(&GEN_STRING_END) {
lines.remove(i);
lines.remove(i);
break;
}
max_count -= 1;
if (max_count <= 0) {
break;
}
lines.remove(i);
}
break;
}
}
Ok(lines)
}
pub fn replace_line(funcs: Vec<String>, file: &str, class_name: &str) -> Result<()> {
let mut objects: Vec<&str> = class_name.split("_").collect();
objects.pop();
objects.push("interface");
let interface_name = objects.join("_");
let mut lines = BufReader::new(OpenOptions::new().read(true).open(file).unwrap())
.lines()
.map(|line| line.unwrap())
.collect::<Vec<String>>();
let mut lines = remove_generated(&mut lines)?;
let class_string = "class ".to_owned() + class_name;
let mut offset = 4;
for i in 0..lines.len() {
if lines[i].contains(&class_string) {
lines.remove(i);
lines.insert(
i,
"class ".to_owned() + class_name + " : " + "public " + interface_name.as_str(),
);
lines.insert(i, " public:".to_owned());
lines.insert(i, "{".to_owned());
lines.insert(i, "class ".to_owned() + interface_name.as_str());
lines.insert(i, GEN_STRING_START.to_owned());
for item in funcs.iter() {
let virtual_func = String::from("\tvirtual ") + &item + " = 0;";
lines.insert(i + offset, virtual_func);
offset += 1;
}
lines.insert(i + offset, "};".to_owned());
lines.insert(i + offset + 1, GEN_STRING_END.to_owned());
lines.insert(i + offset + 2, "".to_owned());
break;
}
}
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(file)
.unwrap();
for line in lines {
writeln!(file, "{}", line).unwrap();
}
Ok(())
}