jabyengine/src/Tools/psxcdgen_ex/src/lib.rs

90 lines
3.2 KiB
Rust

pub use tool_helper::{Error, ErrorString};
pub mod config_reader;
pub mod encoder;
pub mod file_writer;
pub mod types;
use tool_helper::{format_if_error, Output, read_file};
use types::{CDDesc, Directory};
pub type CalculateLBAFunction = fn(&mut types::CDDesc);
pub fn process(config: config_reader::Configuration, calculate_lba: CalculateLBAFunction) -> Result<CDDesc, Error> {
let mut cd_desc = parse_configuration(config)?;
calculate_lba(&mut cd_desc);
Ok(cd_desc)
}
pub fn dump_content(cd_desc: &CDDesc, mut out: Output) -> Result<(), Error> {
fn write_intro(out: &mut Output) -> Result<(), Error> {
writeln!(out, "File: <File name> @<Track relative LBA> - <Size in Bytes>/<Extended size in bytes>")?;
writeln!(out, "Dir: <Directory name> @<Track relative LBA>")?;
writeln!(out, "")?;
Ok(())
}
fn dump_dir(dir: &Directory, out: &mut Output, indent: usize) -> Result<(), Error> {
const INDENT_STEP:usize = 4;
for file in dir.file_iter() {
let file = file.borrow();
let file_name = file.name.as_string().unwrap_or("<No name>".to_owned());
let file_lba = file.get_track_rel_lba();
let file_size = file.properties.get_real_size();
let file_ex_size = file.get_extended_size();
writeln!(out, "{:indent$}File: {} @{} - {}/{}", " ", file_name, file_lba, file_size, file_ex_size, indent=indent)?;
}
for dir in dir.dir_iter() {
let dir = dir.borrow();
let dir_name = dir.name.as_str().unwrap_or("<No name>");
let dir_lba = dir.get_track_rel_lba();
writeln!(out, "{:indent$}Dir: {} @{}", " ", dir_name, dir_lba, indent=indent)?;
dump_dir(&dir, out, indent + INDENT_STEP)?;
}
Ok(())
}
format_if_error!(write_intro(&mut out), "Writing content dump intro failed with: {error_text}")?;
format_if_error!(dump_dir(&cd_desc.root.borrow(), &mut out, 0), "Creating content dump failed with: {error_text}")
}
fn parse_configuration(config: config_reader::Configuration) -> Result<CDDesc, Error> {
fn parse_dir(dst_dir: &mut types::Directory, src_dir: config_reader::Directory) -> Result<(), Error> {
for member in src_dir.into_iter() {
match member {
config_reader::DirMember::Directory(dir) => {
let mut new_dir = types::Directory::new(dir.name.as_str())?;
parse_dir(&mut new_dir, dir)?;
dst_dir.add_dir(new_dir);
},
config_reader::DirMember::File(file) => {
dst_dir.add_file(types::File::new_regular(file.name.as_str(), read_file(file.path)?)?);
},
}
}
Ok(())
}
let cd_desc = CDDesc::new();
if let Some(publisher) = config.publisher {
cd_desc.pvd.borrow_mut().set_publisher(publisher);
}
if let Some(license_path) = config.license_path {
cd_desc.system_area.borrow_mut().license_file_path = Some(license_path);
}
parse_dir(&mut cd_desc.root.borrow_mut(), config.root)?;
Ok(cd_desc)
}