midia 0.1.1

A simple wrapper for writing the midi file easier.
Documentation
mod event;
mod header;
pub mod pitch;
pub mod track;
pub mod typ;
mod util;

use std::{fmt::Display, fs::File, io::Write};

use typ::TrackType;

use crate::{header::MidiHeader, track::MidiTrack};

pub struct MidiWriter {
    data: MidiData,
}

impl MidiWriter {
    pub fn new(typ: TrackType, track_number: u16, bpm: u16) -> Self {
        let mut data = MidiData::new();
        let header = MidiHeader::new(typ, track_number, bpm);
        data.push_data(header);
        Self { data }
    }

    pub fn add_track(&mut self, track: MidiTrack) -> &mut Self {
        self.data.push_data(track);
        self
    }

    pub fn write(&self, path: &str) {
        let mut file = File::create(path).unwrap();
        file.write_all(&self.data.0).unwrap();
    }
}

impl Display for MidiData {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let data_str = self
            .0
            .iter()
            .map(|byte| format!("{:02x}", byte))
            .collect::<Vec<_>>();
        let str = data_str.join(" ");
        write!(f, "{}", str)
    }
}

#[derive(Default)]
pub struct MidiData(Vec<u8>);

impl MidiData {
    pub fn new() -> Self {
        Self(vec![])
    }

    pub fn push_str(&mut self, s: &str) {
        self.0.append(&mut s.as_bytes().to_vec());
    }

    pub fn push_byte(&mut self, byte: u8) {
        self.0.push(byte);
    }

    pub fn push_word(&mut self, word: u16) {
        self.0.append(&mut word.to_be_bytes().to_vec());
    }

    pub fn push_dword(&mut self, dword: u32) {
        self.0.append(&mut dword.to_be_bytes().to_vec());
    }

    pub fn push_bytes(&mut self, mut bytes: Vec<u8>) {
        self.0.append(&mut bytes);
    }

    pub fn push_data(&mut self, data: impl IntoMidiData) {
        self.0.append(&mut data.into_midi_data().0);
    }
}

pub trait IntoMidiData {
    fn into_midi_data(self) -> MidiData;
}