use indexmap::IndexMap;
use serde_json::{json, Value};
use std::fs;
use std::path::{Path, PathBuf};
fn print_result(
c_success: &mut i32,
c_failed: &mut i32,
v_failed: &mut Vec<String>,
c_total_maps: &mut i32,
) {
println!(
"Modified {} out of {} maps successfully!",
*c_success, *c_total_maps
);
println!("Maps failed to modify: {}", *c_failed);
if *c_failed > 0 {
println!("In these maps, 'map.json' was missing:");
for map in v_failed {
println!(" {}", map);
}
}
}
fn remove_attribute(value: &str, map: &mut IndexMap<String, Value>, c_success: &mut i32) {
if value == "connections" {
map.insert(value.to_owned(), serde_json::Value::Null);
*c_success += 1;
} else {
map.insert(value.to_owned(), json!([]));
*c_success += 1;
}
}
fn enter_subdir_and_delete(
subdir_path: &PathBuf,
value: &str,
c_success: &mut i32,
c_failed: &mut i32,
v_failed: &mut Vec<String>,
) -> Result<(), Box<dyn std::error::Error>> {
if subdir_path.is_dir() {
let subdir_name = subdir_path.file_name().unwrap().to_str().unwrap();
let full_dir_name_as_string = format!("./data/maps/{}/map.json", subdir_name);
let full_dir_name = Path::new(&full_dir_name_as_string);
if full_dir_name.exists() {
for file in fs::read_dir(&subdir_path)? {
let file = file?.path();
if !file.is_dir() {
if file.file_name().and_then(|n| n.to_str()) == Some("map.json") {
let contents =
fstream::read_text(&file).expect("Error: Failed to read 'map.json'");
let mut map: IndexMap<String, Value> = serde_json::from_str(&contents)
.expect("Error: Failed to correctly read IndexMap of 'map.json', check for any last changes you made to any map!");
remove_attribute(value, &mut map, c_success);
let modified_json = serde_json::to_string_pretty(&map).expect(
"Error: Failed to correctly deserialize IndexMap of 'map.json'.",
);
fstream::write_text(&file, modified_json, true)
.expect("Error: Failed to write to 'map.json'");
}
}
}
} else {
*c_failed += 1;
v_failed.push(full_dir_name.to_str().unwrap().to_string());
}
}
Ok(())
}
pub fn execute_del(value: &str) -> Result<(), Box<dyn std::error::Error>> {
let mut c_success = 0;
let mut c_failed = 0;
let mut v_failed: Vec<String> = vec![];
let mut c_total_maps = 0;
let is_attribute = value == "connections"
|| value == "object_events"
|| value == "bg_events"
|| value == "warp_events"
|| value == "coord_events";
if is_attribute {
let m_path = Path::new("./data/maps/");
if m_path.is_dir() {
for entry in fs::read_dir(m_path)? {
let subdir_path = entry?.path(); enter_subdir_and_delete(
&subdir_path,
value,
&mut c_success,
&mut c_failed,
&mut v_failed,
)?;
if subdir_path.is_dir() {
c_total_maps += 1;
}
}
print_result(
&mut c_success,
&mut c_failed,
&mut v_failed,
&mut c_total_maps,
); } else {
eprintln!("Error: Directory '{}' not found, make sure that the executable is located in the root of your 3rd Generation project!", m_path.display());
}
} else if !is_attribute {
eprintln!("Error: The given attribute is not a valid attribute, use '--help' for more information.");
}
Ok(())
}