libdaw 0.2.0

A library for Rust for making programmable DAWs
Documentation
use std::sync::{Arc, Mutex};

use crate::parse::{numeric_adjustment, IResult};
use crate::pitch::{Pitch, PitchClass, PitchName};
use nom::character::complete::i8;
use nom::{character::complete::one_of, combinator::opt, multi::fold_many0};

pub fn pitch_name(input: &str) -> IResult<&str, PitchName> {
    let (input, note) = one_of("cdefgabCDEFGAB")(input)?;
    let note = match note {
        'C' | 'c' => PitchName::C,
        'D' | 'd' => PitchName::D,
        'E' | 'e' => PitchName::E,
        'F' | 'f' => PitchName::F,
        'G' | 'g' => PitchName::G,
        'A' | 'a' => PitchName::A,
        'B' | 'b' => PitchName::B,
        _ => unreachable!(),
    };
    Ok((input, note))
}
fn adjustment_symbol(input: &str) -> IResult<&str, f64> {
    let (input, symbol) = one_of("#b♭♯𝄳𝄫𝄪𝄲♮,'")(input)?;
    let adjustment = match symbol {
        '𝄫' => -2.0,
        'b' => -1.0,
        'f' => -1.0,
        ',' => -1.0,
        '' => -1.0,
        '𝄳' => -0.5,
        '' => 0.0,
        '𝄲' => 0.5,
        '#' => 1.0,
        's' => 1.0,
        '' => 1.0,
        '\'' => 1.0,
        '𝄪' => 2.0,
        _ => unreachable!(),
    };
    Ok((input, adjustment))
}

fn symbol_adjustments(input: &str) -> IResult<&str, f64> {
    fold_many0(adjustment_symbol, || 0.0f64, |acc, item| acc + item)(input)
}

fn adjustment(input: &str) -> IResult<&str, f64> {
    let (input, symbolic_adjustment) = symbol_adjustments(input)?;
    let (input, numeric_adjustment) = opt(numeric_adjustment)(input)?;
    Ok((
        input,
        symbolic_adjustment + numeric_adjustment.unwrap_or(0.0),
    ))
}

pub fn pitch_class(input: &str) -> IResult<&str, PitchClass> {
    let (input, note) = pitch_name(input)?;
    let (input, adjustment) = adjustment(input)?;
    Ok((
        input,
        PitchClass {
            name: note,
            adjustment,
        },
    ))
}

pub fn pitch(input: &str) -> IResult<&str, Pitch> {
    let (input, pitch_class) = pitch_class(input)?;
    let (input, octave) = i8(input)?;
    Ok((
        input,
        Pitch {
            pitch_class: Arc::new(Mutex::new(pitch_class)),
            octave,
        },
    ))
}