use crate::{
fs::{self, Filesystem},
song::{self, SongMemory},
};
use std::{
fs::{File, create_dir_all},
io::{self, Read, Write},
path::Path,
};
use thiserror::Error;
pub struct SRam {
pub working_memory_song: SongMemory,
pub filesystem: Filesystem,
}
impl SRam {
pub fn new() -> Self {
Self {
working_memory_song: SongMemory::new(),
filesystem: Filesystem::new(),
}
}
pub fn from_reader<R>(mut reader: R) -> Result<Self, FromReaderError>
where
R: Read,
{
let working_memory_song = SongMemory::from_reader(&mut reader)?;
let filesystem = Filesystem::from_reader(&mut reader)?;
Ok(Self {
working_memory_song,
filesystem,
})
}
pub fn from_path<P>(path: P) -> Result<Self, FromPathError>
where
P: AsRef<Path>,
{
let file = File::open(path)?;
let sram = Self::from_reader(file)?;
Ok(sram)
}
pub fn to_writer<W>(&self, mut writer: W) -> Result<(), io::Error>
where
W: Write,
{
self.working_memory_song.to_writer(&mut writer)?;
self.filesystem.to_writer(writer)
}
pub fn to_path<P>(&self, path: P) -> Result<(), io::Error>
where
P: AsRef<Path>,
{
let path = path.as_ref();
create_dir_all(path.parent().unwrap())?;
self.to_writer(File::create(path)?)
}
}
impl Default for SRam {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Error)]
pub enum FromReaderError {
#[error("Reading the working memory song failed")]
WorkingSong(#[from] song::FromReaderError),
#[error("Reading the filesystem failed")]
Filesystem(#[from] fs::FromReaderError),
}
#[derive(Debug, Error)]
pub enum FromPathError {
#[error("Opening the file failed")]
FileOpen(#[from] io::Error),
#[error("Reading the SRAM from file failed")]
Read(#[from] FromReaderError),
}