beatblox_midi 0.1.0

This crate help with parsing data from .mid files and returns a format compatible with netsblox.
Documentation
use num_traits;

pub const POSSIBLE_NOTE_LENGTHS: [f32; 21] = [
    0.0625, 0.09375, 0.109375, 0.125, 0.1875, 0.21875, 
    0.25, 0.375, 0.4375, 0.5, 0.75, 0.875, 1.0, 1.5, 
    1.75, 2.0, 3.0, 3.5, 4.0, 6.0, 7.0
];

#[derive(Clone, PartialEq, Eq)]
pub enum NoteDuration { 
    WHOLE, 
    HALF, 
    QUARTER, 
    EIGHTH, 
    SIXTEENTH, 
    THIRTYSECOND, 
    SIXTYFOURTH,
    NaN,
}

#[derive(Clone)]
pub enum NoteDurationModifier {
    None,
    Dotted,
    DoubleDotted,
}

#[derive(Clone)]
pub struct Track {
    pub name: String,
    pub notes: Vec<NoteWrapper>
}

#[derive(Clone)]
pub enum NoteWrapper {
    PlainNote(Note),
    ModifiedNote(NoteModifier),
    Rest(Note),
}

#[derive(Clone)]
pub enum NoteModifier {
    TiedNote(Vec<NoteWrapper>),
}

#[derive(Clone)]
pub struct Note {
    pub value: u8,
    pub duration: (NoteDuration, NoteDurationModifier),
    pub velocity: u8,
}

#[derive(Clone, Copy)]
pub struct TimeSignature {
    pub beat_count: u8,
    pub beat_type: u8,
    pub time_of_occurance: u32,
}

pub fn beat_type_map(beats: f32, beat_type: f32) -> (NoteDuration, NoteDurationModifier) {
    match beats * num_traits::pow(beat_type, 2) {
        112.0 => return (NoteDuration::WHOLE, NoteDurationModifier::DoubleDotted),
        96.0 => return (NoteDuration::WHOLE, NoteDurationModifier::Dotted),
        64.0 => return (NoteDuration::WHOLE, NoteDurationModifier::None),
        56.0 => return (NoteDuration::HALF, NoteDurationModifier::DoubleDotted),
        48.0 => return (NoteDuration::HALF, NoteDurationModifier::Dotted),
        32.0 => return (NoteDuration::HALF, NoteDurationModifier::None),
        28.0 => return (NoteDuration::QUARTER, NoteDurationModifier::DoubleDotted),
        24.0 => return (NoteDuration::QUARTER, NoteDurationModifier::Dotted),
        16.0 => return (NoteDuration::QUARTER, NoteDurationModifier::None),
        14.0 => return (NoteDuration::EIGHTH, NoteDurationModifier::DoubleDotted),
        12.0 => return (NoteDuration::EIGHTH, NoteDurationModifier::Dotted),
        8.0 => return (NoteDuration::EIGHTH, NoteDurationModifier::None),
        7.0 => return (NoteDuration::SIXTEENTH, NoteDurationModifier::DoubleDotted),
        6.0 => return (NoteDuration::SIXTEENTH, NoteDurationModifier::Dotted),
        4.0 => return (NoteDuration::SIXTEENTH, NoteDurationModifier::None),
        3.5 => return (NoteDuration::THIRTYSECOND, NoteDurationModifier::DoubleDotted),
        3.0 => return (NoteDuration::THIRTYSECOND, NoteDurationModifier::Dotted),
        2.0 => return (NoteDuration::THIRTYSECOND, NoteDurationModifier::None),
        1.75 => return (NoteDuration::SIXTYFOURTH, NoteDurationModifier::DoubleDotted),
        1.5 => return (NoteDuration::SIXTYFOURTH, NoteDurationModifier::Dotted),
        1.0 => return (NoteDuration::SIXTYFOURTH, NoteDurationModifier::None),
        _ => return (NoteDuration::NaN, NoteDurationModifier::None),
    }
}

pub fn note_wrapper_builder(
    value: u8, duration: (NoteDuration, NoteDurationModifier), velocity: u8) -> NoteWrapper {
    if value == 255 {
        return NoteWrapper::Rest(Note {value: value, duration: duration, velocity: velocity});
    }
    return NoteWrapper::PlainNote(Note {value: value, duration: duration, velocity: velocity});
}

pub fn print_note_wrapper(note: &NoteWrapper) {
    match note {
        NoteWrapper::PlainNote(n) => {
            let duration_str = note_duration_str(&n.duration.0);
            let mod_str = note_duration_mod_str(&n.duration.1);
            println!("Note: {} for duration {} + {}", n.value, duration_str, mod_str);
        },
        NoteWrapper::Rest(r) => {
            let duration_str = note_duration_str(&r.duration.0);
            let mod_str = note_duration_mod_str(&r.duration.1);
             println!("Rest for duration {} + {}", duration_str, mod_str);
        },
        NoteWrapper::ModifiedNote(v) => {
            let NoteModifier::TiedNote(t) = v;
            println!("====Tied Notes====");
            for n in t { 
                print_note_wrapper(n); 
            }
            println!("==================");
        },
    }
}

fn note_duration_str(note_duration: &NoteDuration) -> &str {
    match note_duration {
        NoteDuration::WHOLE => return "whole note",
        NoteDuration::HALF => return "half note", 
        NoteDuration::QUARTER => return "quarter note", 
        NoteDuration::EIGHTH => return "eighth note", 
        NoteDuration::SIXTEENTH => return "sixteenth note", 
        NoteDuration::THIRTYSECOND => return "thirtysecond note", 
        NoteDuration::SIXTYFOURTH => return "sixtyfourth note",
        NoteDuration::NaN => return "unknown note",
    }
}

fn note_duration_mod_str(note_duration_modifier: &NoteDurationModifier) -> &str {
    match note_duration_modifier {
        NoteDurationModifier::None => return "none",
        NoteDurationModifier::Dotted => return "dotted",
        NoteDurationModifier::DoubleDotted => return "double dotted",
    }
}