use crate::prelude::*;
#[doc = r#"
Identifies a track chunk header. Only metadata
contained is the length, in bytes, of the
track chunk's body.
The body bytes are parsed into [`TrackEvent`]s.
"#]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TrackChunkHeader {
length: u32,
}
impl TrackChunkHeader {
pub(crate) fn read<'slc, 'r, R>(reader: &'r mut Reader<R>) -> ReadResult<Self>
where
R: MidiSource<'slc>,
{
let length: BytesConst<'_, 4> = reader.read_exact_size()?;
let length = u32::from_be_bytes(*length);
Ok(Self { length })
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> u32 {
self.length
}
}
#[doc = r#"
Contains the whole length of the track chunk
"#]
#[allow(dead_code)]
pub struct RawTrackChunk<'a>(Bytes<'a>);
impl<'a> RawTrackChunk<'a> {
pub(crate) fn read<'slc, 'r, R>(reader: &'r mut Reader<R>) -> ReadResult<Self>
where
R: MidiSource<'slc>,
'slc: 'a,
{
let length = u32::from_be_bytes(*reader.read_exact_size()?);
let track_event_bytes = reader.read_exact(length as usize)?;
Ok(Self(track_event_bytes))
}
pub fn events(self) -> ReadResult<Vec<TrackEvent<'a>>> {
let mut events: Vec<TrackEvent<'a>> = Vec::with_capacity(self.0.len());
let mut reader = Reader::from_bytes(self.0);
let mut running_status = None;
loop {
match TrackEvent::read(&mut reader, &mut running_status) {
Ok(e) => events.push(e),
Err(err) => {
if err.is_out_of_bounds() {
break;
} else {
return Err(err);
}
}
}
}
Ok(events)
}
}