#![warn(clippy::pedantic)]
use parser::inits::announcements::DFAnnouncement;
use parser::raws::RawModuleLocation;
use parser::{DFParser, RawsStyleSerializable, TypedJsonSerializable};
use std::path::{Path, PathBuf};
use walkdir::DirEntry;
mod parser;
#[cfg(feature = "tauri")]
mod tauri_lib;
mod util;
pub fn parse_module_location<P: AsRef<Path>>(raw_module_location: &P) -> String {
let raw_module_location_path = raw_module_location.as_ref();
if !raw_module_location_path.exists() {
log::error!(
"Provided module path for parsing doesn't exist!\n{}",
raw_module_location_path.display()
);
return String::new();
}
if !raw_module_location_path.is_dir() {
log::error!(
"Raw module path needs to be a directory {}",
raw_module_location_path.display()
);
return String::new();
}
let module_location = RawModuleLocation::from_sourced_directory(
raw_module_location_path
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default(),
);
let raw_module_iter: Vec<DirEntry> =
util::subdirectories(PathBuf::from(raw_module_location_path)).unwrap_or_default();
log::info!(
"{num} raw modules located in {location:?}",
num = raw_module_iter.len(),
location = module_location
);
let mut all_json: Vec<String> = Vec::new();
for raw_module_directory in raw_module_iter {
all_json.push(parse_raw_module(&raw_module_directory.path()));
}
format!("[{}]", all_json.join(","))
}
pub fn parse_info_txt_in_location<P: AsRef<Path>>(raw_module_location: &P) -> String {
let raw_module_location_path = raw_module_location.as_ref();
if !raw_module_location_path.exists() {
log::error!(
"Provided module path for parsing doesn't exist!\n{}",
raw_module_location_path.display()
);
return String::new();
}
if !raw_module_location_path.is_dir() {
log::error!(
"Raw module path needs to be a directory {}",
raw_module_location_path.display()
);
return String::new();
}
let module_location = RawModuleLocation::from_sourced_directory(
raw_module_location_path
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default(),
);
let raw_module_iter: Vec<DirEntry> =
util::subdirectories(PathBuf::from(raw_module_location_path)).unwrap_or_default();
log::info!(
"{num} raw modules located in {location:?}",
num = raw_module_iter.len(),
location = module_location
);
let mut all_json: Vec<String> = Vec::new();
for raw_module_directory in raw_module_iter {
all_json.push(parse_info_txt_in_module(&raw_module_directory.path()));
}
format!("[{}]", all_json.join(","))
}
pub fn parse_game_raws<P: AsRef<Path>>(df_game_path: &P) -> String {
let game_path = Path::new(df_game_path.as_ref());
if !game_path.exists() {
log::error!(
"Provided game path for parsing doesn't exist!\n{}",
game_path.display()
);
return String::new();
}
if !game_path.is_dir() {
log::error!("Game path needs to be a directory {}", game_path.display());
return String::new();
}
if !game_path.join("gamelog.txt").exists() {
log::warn!("Unable to find gamelog.txt in game directory. Is it valid?");
}
let data_path = game_path.join("data");
let vanilla_path = data_path.join("vanilla");
let installed_mods_path = data_path.join("installed_mods");
let workshop_mods_path = game_path.join("mods");
let all_json = vec![
parse_module_location(&vanilla_path),
parse_module_location(&installed_mods_path),
parse_module_location(&workshop_mods_path),
];
let non_empty_json: Vec<String> = all_json
.into_iter()
.filter(|s| !String::is_empty(s))
.collect();
format!("[{}]", non_empty_json.join(","))
}
pub fn parse_raw_module<P: AsRef<Path>>(raw_module_path: &P) -> String {
DFParser::parse_raw_module_to_json_string(raw_module_path)
}
pub fn parse_game_raws_to_file<P: AsRef<Path>>(df_game_path: &P, out_filepath: &P) {
let parsed_json_string = parse_game_raws(df_game_path);
util::write_json_string_to_file(&parsed_json_string, out_filepath);
}
pub fn parse_info_txt_in_game_dir_to_file<P: AsRef<Path>>(df_game_path: &P, out_filepath: &P) {
let parsed_json_string = parse_info_txt_in_game_dir(df_game_path);
util::write_json_string_to_file(&parsed_json_string, out_filepath);
}
pub fn parse_info_txt_in_module<P: AsRef<Path>>(raw_module_directory: &P) -> String {
let dfraw_module_info = DFParser::parse_info_file_from_module_directory(raw_module_directory);
match dfraw_module_info.to_typed_json_string() {
Ok(s) => {
return s;
}
Err(e) => {
log::error!("Failure to serialize parsed raw data\n{}", e);
}
}
String::new()
}
pub fn parse_single_raw_file<P: AsRef<Path>>(raw_file: &P) -> String {
DFParser::parse_single_raw_file_to_json_string(raw_file)
}
pub fn parse_info_txt_in_game_dir<P: AsRef<Path>>(df_game_path: &P) -> String {
let game_path = match util::path_from_game_directory(df_game_path) {
Ok(p) => p,
Err(e) => {
log::error!("Game Path Error: {}", e);
return String::new();
}
};
let data_path = game_path.join("data");
let vanilla_path = data_path.join("vanilla");
let installed_mods_path = data_path.join("installed_mods");
let workshop_mods_path = game_path.join("mods");
let all_json = vec![
parse_info_txt_in_location(&vanilla_path),
parse_info_txt_in_location(&installed_mods_path),
parse_info_txt_in_location(&workshop_mods_path),
];
format!("[{}]", all_json.join(","))
}
pub fn parse_single_raw_file_to_file<P: AsRef<Path>>(raw_file: &P, out_filepath: &P) {
let parsed_json_string = parse_single_raw_file(raw_file);
util::write_json_string_to_file(&parsed_json_string, out_filepath);
}
pub fn parse_raw_module_to_file<P: AsRef<Path>>(module_path: &P, out_filepath: &P) {
let parsed_json_string = parse_raw_module(module_path);
util::write_json_string_to_file(&parsed_json_string, out_filepath);
}
pub fn parse_module_location_to_file<P: AsRef<Path>>(
raw_module_location_path: &P,
out_filepath: &P,
) {
let parsed_json_string = parse_module_location(raw_module_location_path);
util::write_json_string_to_file(&parsed_json_string, out_filepath);
}
#[cfg(feature = "tauri")]
pub fn parse_game_raws_with_tauri_emit<P: AsRef<Path>>(
df_game_path: &P,
window: tauri::Window,
) -> String {
tauri_lib::parse_game_raws_with_tauri_emit(df_game_path, window)
}
#[cfg(feature = "tauri")]
#[allow(clippy::cast_precision_loss)]
pub fn parse_location_with_tauri_emit<P: AsRef<Path>>(
location_path: &P,
window: tauri::Window,
) -> String {
tauri_lib::parse_location_with_tauri_emit(location_path, window)
}
pub fn parse_announcements_txt<P: AsRef<Path>>(announcements_txt_path: &P) -> String {
let x = DFAnnouncement::parse(announcements_txt_path);
let Ok(y) = serde_json::to_string(&x) else {
log::error!("Unable to convert into json");
return String::new();
};
y
}
pub fn parse_announcements_txt_to_file<P: AsRef<Path>>(
announcements_txt_path: &P,
out_filepath: &P,
) {
let x = DFAnnouncement::parse(announcements_txt_path);
let Ok(y) = serde_json::to_string(&x) else {
log::error!("Unable to convert into json");
return;
};
util::write_json_string_to_file(&y, out_filepath);
}
pub fn write_announcements_txt_from_json<P: AsRef<Path>>(
announcements_txt_path: &P,
announcements_vec_json: &str,
) {
let announcements_vec: Vec<DFAnnouncement> = match serde_json::from_str(announcements_vec_json)
{
Ok(a) => a,
Err(e) => {
log::error!("{e:?}");
return;
}
};
let mut serializable_announcements: Vec<Box<dyn RawsStyleSerializable>> = Vec::new();
for announcement in announcements_vec {
serializable_announcements.push(Box::new(announcement));
}
let x = util::raws_stringify_df_vec(serializable_announcements);
util::write_raws_string_vec_to_file(&x, announcements_txt_path);
}