use crate::error::LibResult;
use crate::scribe::Scribe;
use crate::{Division, Error};
use snafu::ResultExt;
use std::convert::TryFrom;
use std::io::Write;
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Hash)]
pub struct Header {
format: Format,
division: Division,
}
impl Header {
pub fn new(format: Format, division: Division) -> Self {
Self { format, division }
}
pub fn format(&self) -> &Format {
&self.format
}
pub fn division(&self) -> &Division {
&self.division
}
pub(crate) fn write<W: Write>(&self, w: &mut Scribe<W>, ntracks: u16) -> LibResult<()> {
write!(w, "MThd").context(wr!())?;
w.write_all(&6u32.to_be_bytes()).context(wr!())?;
w.write_all(&(self.format as u16).to_be_bytes())
.context(wr!())?;
w.write_all(&ntracks.to_be_bytes()).context(wr!())?;
self.division.write(w)?;
Ok(())
}
}
#[repr(u16)]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash, Default)]
pub enum Format {
Single = 0,
#[default]
Multi = 1,
Sequential = 2,
}
impl Format {
pub(crate) fn from_u16(value: u16) -> LibResult<Self> {
match value {
0 => Ok(Format::Single),
1 => Ok(Format::Multi),
2 => Ok(Format::Sequential),
_ => crate::error::OtherSnafu { site: site!() }.fail(),
}
}
}
impl TryFrom<u16> for Format {
type Error = Error;
fn try_from(value: u16) -> crate::Result<Self> {
Ok(Self::from_u16(value)?)
}
}