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
}
}
}}