use err::LoadErr;
use impulse_format::{header, pattern};
use crate::project::song::Song;
pub mod err;
pub mod impulse_format;
#[derive(Debug, Clone, Copy)]
pub struct InFilePtr(pub(crate) std::num::NonZeroU32);
impl InFilePtr {
pub fn move_to_self<S: std::io::Seek>(self, seeker: &mut S) -> Result<(), std::io::Error> {
seeker
.seek(std::io::SeekFrom::Start(self.0.get().into()))
.map(|_| ())
}
}
pub fn parse_song<R: std::io::Read + std::io::Seek>(reader: &mut R) -> Result<Song, LoadErr> {
let mut defect_handler = |_| ();
let header = header::ImpulseHeader::parse(reader, &mut defect_handler)?;
let mut song = Song::default();
song.copy_values_from_header(&header);
for (idx, ptr) in header
.pattern_offsets
.iter()
.enumerate()
.flat_map(|(idx, ptr)| ptr.map(|ptr| (idx, ptr)))
{
ptr.move_to_self(reader)?;
let pattern = pattern::parse_pattern(reader, &mut defect_handler)?;
song.patterns[idx] = pattern;
}
Ok(song)
}