relax trait requirements, rename failable methods with 'try'

This commit is contained in:
Breval Ferrari 2025-03-14 22:53:16 -04:00
parent 58cf13a564
commit f4e8f7c276
No known key found for this signature in database
GPG key ID: F71E304D6400AB8E
8 changed files with 163 additions and 33 deletions

View file

@ -19,3 +19,4 @@ derive-new = "0.7"
strum = { version = "0.26", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
dasp_sample = "0.11.0" dasp_sample = "0.11.0"
derive_wrapper = "0.1" derive_wrapper = "0.1"
symphonia = { version = "0.5.4", features = ["all"] }

View file

@ -5,7 +5,7 @@ use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
use crate::{Bendable, Bytes, IntoDataBytes, TryFromDataBytes}; use crate::{Bendable, Bytes, IntoDataBytes, TryFromDataBytes};
impl IntoDataBytes for Bytes { impl IntoDataBytes for Bytes {
fn into_bytes(self) -> Bytes { fn into_data_bytes(self) -> Bytes {
self self
} }
} }
@ -13,7 +13,11 @@ impl IntoDataBytes for Bytes {
impl TryFromDataBytes for Bytes { impl TryFromDataBytes for Bytes {
type Error = Infallible; type Error = Infallible;
type Format = (); type Format = ();
fn try_from_bytes(bytes: Bytes, _: Self::Format, _: crate::Crop) -> Result<Self, Self::Error> fn try_from_data_bytes(
bytes: Bytes,
_: Self::Format,
_: crate::Crop,
) -> Result<Self, Self::Error>
where where
Self: Sized, Self: Sized,
{ {

View file

@ -1,4 +1,7 @@
use std::ops::{Deref, DerefMut}; use std::{
convert::Infallible,
ops::{Deref, DerefMut},
};
pub use image::*; pub use image::*;
use num::{ use num::{
@ -6,15 +9,16 @@ use num::{
Zero, Zero,
}; };
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use thiserror::Error;
use crate::{Bendable, IntoDataBytes, TryFromDataBytes}; use crate::{Bendable, Format, FromDataBytes, IntoDataBytes, TryFromDataBytes};
impl<P: Pixel> IntoDataBytes for ImageBuffer<P, Vec<P::Subpixel>> impl<P: Pixel> IntoDataBytes for ImageBuffer<P, Vec<P::Subpixel>>
where where
Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>, Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>,
P::Subpixel: ToBytes, P::Subpixel: ToBytes,
{ {
fn into_bytes(self) -> crate::Bytes { fn into_data_bytes(self) -> crate::Bytes {
self.iter() self.iter()
.flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec()) .flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec())
.collect() .collect()
@ -32,9 +36,9 @@ where
P::Subpixel: ToBytes + FromBytes, P::Subpixel: ToBytes + FromBytes,
<P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>, <P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>,
{ {
type Error = (); type Error = Infallible;
type Format = Dimensions; type Format = Dimensions;
fn try_from_bytes( fn try_from_data_bytes(
bytes: crate::Bytes, bytes: crate::Bytes,
format: Self::Format, format: Self::Format,
crop: crate::Crop, crop: crate::Crop,
@ -70,7 +74,7 @@ where
.collect::<Vec<P::Subpixel>>(), .collect::<Vec<P::Subpixel>>(),
}, },
) )
.ok_or(()) .ok_or_else(|| unreachable!())
} }
} }
@ -87,16 +91,67 @@ where
self self
} }
fn format() -> crate::Format { fn format() -> crate::Format {
crate::Format::Image Format::Image
} }
} }
impl IntoDataBytes for DynamicImage { impl IntoDataBytes for DynamicImage {
fn into_bytes(self) -> crate::Bytes { fn into_data_bytes(self) -> crate::Bytes {
self.into_bytes() self.into_bytes()
} }
} }
#[derive(Debug, Error)]
#[error("this color type is not supported yet... sorry")]
pub struct UnsupportedColorType;
impl TryFromDataBytes for DynamicImage {
type Format = (Dimensions, ColorType);
type Error = UnsupportedColorType;
fn try_from_data_bytes(
bytes: crate::Bytes,
format: Self::Format,
crop: crate::Crop,
) -> Result<Self, Self::Error>
where
Self: Sized,
{
match format.1 {
ColorType::L8 => Ok(DynamicImage::ImageLuma8(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::La8 => Ok(DynamicImage::ImageLumaA8(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgb8 => Ok(DynamicImage::ImageRgb8(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgba8 => Ok(DynamicImage::ImageRgba8(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::L16 => Ok(DynamicImage::ImageLuma16(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::La16 => Ok(DynamicImage::ImageLumaA16(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgb16 => Ok(DynamicImage::ImageRgb16(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgba16 => Ok(DynamicImage::ImageRgba16(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgb32F => Ok(DynamicImage::ImageRgb32F(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
ColorType::Rgba32F => Ok(DynamicImage::ImageRgba32F(ImageBuffer::from_data_bytes(
bytes, format.0, crop,
))),
_ => Err(UnsupportedColorType),
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[cfg(test)] #[cfg(test)]
@ -111,8 +166,8 @@ mod tests {
let image = RgbImage::new(0, 0); let image = RgbImage::new(0, 0);
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
RgbImage::try_from_bytes( RgbImage::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 0, width: 0,
height: 0 height: 0
@ -127,8 +182,8 @@ mod tests {
let image = RgbImage::from_raw(3, 1, vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).unwrap(); let image = RgbImage::from_raw(3, 1, vec![1, 2, 3, 4, 5, 6, 7, 8, 9]).unwrap();
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
RgbImage::try_from_bytes( RgbImage::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 3, width: 3,
height: 1 height: 1
@ -144,8 +199,8 @@ mod tests {
RgbaImage::from_raw(3, 1, vec![1, 2, 3, 0, 4, 5, 6, 1, 7, 8, 9, 2]).unwrap(); RgbaImage::from_raw(3, 1, vec![1, 2, 3, 0, 4, 5, 6, 1, 7, 8, 9, 2]).unwrap();
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
RgbaImage::try_from_bytes( RgbaImage::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 3, width: 3,
height: 1 height: 1
@ -165,8 +220,8 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
ImageBuffer::<Rgb<u16>, Vec<u16>>::try_from_bytes( ImageBuffer::<Rgb<u16>, Vec<u16>>::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 3, width: 3,
height: 1 height: 1
@ -186,8 +241,8 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
ImageBuffer::<Rgb<i16>, Vec<i16>>::try_from_bytes( ImageBuffer::<Rgb<i16>, Vec<i16>>::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 3, width: 3,
height: 1 height: 1
@ -207,8 +262,8 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
Ok(image.clone()), Ok(image.clone()),
Rgb32FImage::try_from_bytes( Rgb32FImage::try_from_data_bytes(
image.into_bytes(), image.into_data_bytes(),
Dimensions { Dimensions {
width: 3, width: 3,
height: 1 height: 1

View file

@ -5,7 +5,7 @@ pub mod txt;
pub(crate) type Bytes = Vec<u8>; pub(crate) type Bytes = Vec<u8>;
pub mod dynamic { mod dynamic {
use std::{ use std::{
fs::File, fs::File,
io::{self, Read}, io::{self, Read},
@ -64,30 +64,32 @@ pub mod dynamic {
} }
} }
use dynamic::*; use std::convert::Infallible;
pub use dynamic::*;
pub trait Bendable: TryFromDataBytes + IntoDataBytes { pub trait Bendable: TryFromDataBytes + IntoDataBytes {
type Unit; type Unit;
fn bend_into<T: Bendable>( fn bend_into<T: TryFromDataBytes + IntoDataBytes>(
self, self,
format: <T as TryFromDataBytes>::Format, format: <T as TryFromDataBytes>::Format,
crop: Crop, crop: Crop,
) -> Result<T, <T as TryFromDataBytes>::Error> { ) -> Result<T, <T as TryFromDataBytes>::Error> {
T::bend_from(self, format, crop) T::try_from_data_bytes(self.into_data_bytes(), format, crop)
} }
fn bend_from<T: Bendable>( fn bend_from<T: TryFromDataBytes + IntoDataBytes>(
b: T, b: T,
format: <Self as TryFromDataBytes>::Format, format: <Self as TryFromDataBytes>::Format,
crop: Crop, crop: Crop,
) -> Result<Self, <Self as TryFromDataBytes>::Error> { ) -> Result<Self, <Self as TryFromDataBytes>::Error> {
Self::try_from_bytes(b.into_bytes(), format, crop) Self::try_from_data_bytes(b.into_data_bytes(), format, crop)
} }
fn map<F: Fn(&Self::Unit) -> Self::Unit + Sync>(self, f: F) -> Self; fn map<F: Fn(&Self::Unit) -> Self::Unit + Sync>(self, f: F) -> Self;
fn format() -> Format; fn format() -> Format;
} }
pub trait IntoDataBytes: Sized { pub trait IntoDataBytes: Sized {
fn into_bytes(self) -> Bytes; fn into_data_bytes(self) -> Bytes;
} }
#[derive(Default)] #[derive(Default)]
@ -100,7 +102,31 @@ pub enum Crop {
pub trait TryFromDataBytes { pub trait TryFromDataBytes {
type Error; type Error;
type Format; type Format;
fn try_from_bytes(bytes: Bytes, format: Self::Format, crop: Crop) -> Result<Self, Self::Error> fn try_from_data_bytes(
bytes: Bytes,
format: Self::Format,
crop: Crop,
) -> Result<Self, Self::Error>
where where
Self: Sized; Self: Sized;
} }
pub trait FromDataBytes {
type Format;
fn from_data_bytes(bytes: Bytes, format: Self::Format, crop: Crop) -> Self
where
Self: Sized;
}
impl<F, T> FromDataBytes for T
where
T: TryFromDataBytes<Error = Infallible, Format = F>,
{
type Format = <T as TryFromDataBytes>::Format;
fn from_data_bytes(bytes: Bytes, format: Self::Format, crop: Crop) -> Self
where
Self: Sized,
{
T::try_from_data_bytes(bytes, format, crop).unwrap_or_else(|_| unreachable!())
}
}

View file

@ -1,3 +1,4 @@
pub use dasp_sample::Sample; pub use dasp_sample::Sample;
mod raw; mod raw;
pub use raw::RawSamples; pub use raw::RawSamples;
mod simphonia;

View file

@ -17,7 +17,7 @@ impl<T> IntoDataBytes for RawSamples<T>
where where
T: Sample + ToBytes, T: Sample + ToBytes,
{ {
fn into_bytes(self) -> crate::Bytes { fn into_data_bytes(self) -> crate::Bytes {
self.as_ref() self.as_ref()
.iter() .iter()
.flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec()) .flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec())
@ -32,7 +32,7 @@ where
{ {
type Error = (); type Error = ();
type Format = (); type Format = ();
fn try_from_bytes( fn try_from_data_bytes(
bytes: crate::Bytes, bytes: crate::Bytes,
_format: Self::Format, _format: Self::Format,
crop: crate::Crop, crop: crate::Crop,

View file

@ -0,0 +1,42 @@
use std::io;
use symphonia::{
core::{
audio::{RawSample, RawSampleBuffer},
io::MediaSourceStream,
probe::Hint,
sample::Sample,
},
default,
};
use crate::TryFromDataBytes;
pub struct Audio<S>(RawSampleBuffer<S>)
where
S: Sample + RawSample;
impl<S> TryFromDataBytes for Audio<S>
where
S: Sample + RawSample,
{
type Error = symphonia::core::errors::Error;
type Format = Hint;
fn try_from_data_bytes(
bytes: crate::Bytes,
format: Self::Format,
crop: crate::Crop,
) -> Result<Self, Self::Error>
where
Self: Sized,
{
let registry = default::get_codecs();
let probe = default::get_probe();
let mediasource = io::Cursor::new(bytes);
let mss = MediaSourceStream::new(Box::new(mediasource), Default::default());
let reader = probe
.format(&format, mss, &Default::default(), &Default::default())?
.format;
todo!()
}
}

View file

@ -7,8 +7,9 @@ description.workspace = true
authors.workspace = true authors.workspace = true
repository.workspace = true repository.workspace = true
keywords.workspace = true keywords.workspace = true
dependencies.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
bingus = { path = "../bingus" }
clap = { version = "4.5.32", features = ["derive"] }