libdaw 0.2.0

A library for Rust for making programmable DAWs
Documentation
mod parse;

use super::{resolve_state::ResolveState, Item};
use crate::{
    metronome::{Beat, Metronome},
    nodes::instrument::Tone,
    parse::IResult,
    pitch::PitchStandard,
};
use nom::{combinator::all_consuming, error::convert_error, Finish as _};
use std::str::FromStr;

#[derive(Debug, Clone)]
pub struct Overlapped(pub Vec<Item>);

impl Overlapped {
    pub(super) fn inner_tones<S>(
        &self,
        offset: Beat,
        metronome: &Metronome,
        pitch_standard: &S,
        state: &ResolveState,
    ) -> impl Iterator<Item = Tone> + 'static
    where
        S: PitchStandard + ?Sized,
    {
        let pitches: Vec<_> = self
            .0
            .iter()
            .flat_map(move |item| item.inner_tones(offset, metronome, pitch_standard, state))
            .collect();
        pitches.into_iter()
    }
    pub fn tones<S>(
        &self,
        offset: Beat,
        metronome: &Metronome,
        pitch_standard: &S,
    ) -> impl Iterator<Item = Tone> + 'static
    where
        S: PitchStandard + ?Sized,
    {
        self.inner_tones(offset, metronome, pitch_standard, &Default::default())
    }

    pub(super) fn inner_length(&self, state: &ResolveState) -> Beat {
        self.0
            .iter()
            .map(|item| item.inner_length(state))
            .max()
            .unwrap_or(Beat::ZERO)
    }

    pub(super) fn inner_duration(&self, state: &ResolveState) -> Beat {
        self.0
            .iter()
            .map(|item| item.inner_duration(state))
            .max()
            .unwrap_or(Beat::ZERO)
    }
    pub fn length(&self) -> Beat {
        self.inner_length(&Default::default())
    }
    pub fn duration(&self) -> Beat {
        self.inner_duration(&Default::default())
    }
    pub fn parse(input: &str) -> IResult<&str, Self> {
        parse::overlapped(input)
    }
}

impl FromStr for Overlapped {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let note = all_consuming(parse::overlapped)(s)
            .finish()
            .map_err(move |e| convert_error(s, e))?
            .1;
        Ok(note)
    }
}