bingus 0.10.0

databending made easy
Documentation
use std::{borrow::Cow, convert::Infallible};

use super::sample::Sample;
use cfg_if::cfg_if;
use derive_wrapper::{AsRef, From};
use num::{
    traits::{FromBytes, ToBytes},
    Zero,
};
#[cfg(feature = "rayon")]
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};

use crate::{Bendable, IntoDataBytes, TryFromDataBytes};

#[derive(From, AsRef)]
pub struct RawSamples<T>(Vec<T>)
where
    T: Sample;

impl<T: Sample> RawSamples<T> {
    pub fn into_inner(self) -> Vec<T> {
        self.0
    }
}

impl<T> IntoDataBytes for RawSamples<T>
where
    T: Sample + ToBytes,
{
    fn into_data_bytes(self) -> crate::Bytes {
        self.as_ref()
            .iter()
            .flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec())
            .collect()
    }
}

impl<T> TryFromDataBytes for RawSamples<T>
where
    T: Sample + FromBytes + ToBytes + Zero,
    <T as FromBytes>::Bytes: Sized + for<'a> TryFrom<&'a [u8]>,
{
    type Error = Infallible;
    type Format = ();
    fn try_from_data_bytes(
        bytes: crate::Bytes,
        _format: Self::Format,
        crop: crate::Crop,
    ) -> Result<Self, Self::Error> {
        Ok(match crop {
            crate::Crop::End => bytes
                .chunks_exact(T::zero().to_ne_bytes().as_ref().len())
                .map(|p| {
                    T::from_ne_bytes(&match <T as FromBytes>::Bytes::try_from(p) {
                        Ok(v) => v,
                        Err(_) => unreachable!("you messed up chunk size!"),
                    })
                })
                .collect::<Vec<T>>(),
            crate::Crop::Start => bytes
                .rchunks_exact(T::zero().to_ne_bytes().as_ref().len())
                .map(|p| {
                    T::from_ne_bytes(&match <T as FromBytes>::Bytes::try_from(p) {
                        Ok(v) => v,
                        Err(_) => unreachable!("you messed up chunk size!"),
                    })
                })
                .collect::<Vec<T>>(),
        }
        .into())
    }
}

cfg_if! {
if #[cfg(feature = "rayon")] {
    impl<T> Bendable for RawSamples<T>
    where
        T: Sample + FromBytes + ToBytes + Zero + Send,
        <T as FromBytes>::Bytes: Sized + for<'a> TryFrom<&'a [u8]>,
        for<'a> Vec<T>: IntoParallelRefMutIterator<'a, Item = &'a mut T>,
    {
        type Unit = T;
        fn map<F: Fn(Cow<Self::Unit>) -> Self::Unit + Sync>(mut self, f: F) -> Self {
            self.0.par_iter_mut().for_each(|e| *e = f(Cow::Borrowed(e)));
            self
        }
        fn format() -> crate::dynamic::Format {
            crate::Format::Sound
        }
    }
} else {
    impl<T> Bendable for RawSamples<T>
    where
        T: Sample + FromBytes + ToBytes + Zero + Send,
        <T as FromBytes>::Bytes: Sized + for<'a> TryFrom<&'a [u8]>,
    {
        type Unit = T;
        fn map<F: Fn(Cow<Self::Unit>) -> Self::Unit + Sync>(mut self, f: F) -> Self {
            self.0.iter_mut().for_each(|e| *e = f(Cow::Borrowed(e)));
            self
        }
    }
}}