rpgm_tool/commands/compile_assets/
file_sink.rsuse anyhow::bail;
use anyhow::Context;
use std::fs::File;
use std::io::BufWriter;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug)]
pub enum FileSink {
Dir {
base_path: PathBuf,
},
Rgssad {
writer: rgssad::Writer<BufWriter<File>>,
},
}
impl FileSink {
pub fn new_dir(path: &Path, overwrite: bool) -> anyhow::Result<Self> {
if path.try_exists()? {
if overwrite {
std::fs::remove_dir_all(path)?;
} else {
bail!("output path exists");
}
}
std::fs::create_dir_all(path)
.with_context(|| format!("failed to create dir at \"{}\"", path.display()))?;
Ok(Self::Dir {
base_path: path.into(),
})
}
pub fn new_rgssad(path: &Path, overwrite: bool) -> anyhow::Result<Self> {
if path.try_exists()? {
if overwrite {
std::fs::remove_file(path)?;
} else {
bail!("output path exists");
}
}
let file = File::create_new(path)?;
let file = BufWriter::new(file);
let mut writer = rgssad::Writer::new(file);
writer.write_header()?;
Ok(Self::Rgssad { writer })
}
pub fn write_file<R>(
&mut self,
path_components: &[&str],
size: u32,
mut reader: R,
) -> anyhow::Result<()>
where
R: Read,
{
match self {
Self::Dir { base_path } => {
let mut path = base_path.clone();
path.extend(path_components);
if let Some(parent_path) = path.parent() {
std::fs::create_dir_all(parent_path)?;
}
let mut file = File::create_new(path)?;
std::io::copy(&mut reader, &mut file)?;
file.flush()?;
file.sync_all()?;
}
Self::Rgssad { writer } => {
let path = path_components.join("\\");
writer.write_file(&path, size, reader)?;
}
}
Ok(())
}
pub fn finish(&mut self) -> anyhow::Result<()> {
match self {
Self::Dir { .. } => {}
Self::Rgssad { writer } => {
let buf_writer = writer.get_mut();
buf_writer.flush()?;
let file = buf_writer.get_mut();
file.sync_all()?;
}
}
Ok(())
}
}