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"] }
dasp_sample = "0.11.0"
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};
impl IntoDataBytes for Bytes {
fn into_bytes(self) -> Bytes {
fn into_data_bytes(self) -> Bytes {
self
}
}
@ -13,7 +13,11 @@ impl IntoDataBytes for Bytes {
impl TryFromDataBytes for Bytes {
type Error = Infallible;
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
Self: Sized,
{

View file

@ -1,4 +1,7 @@
use std::ops::{Deref, DerefMut};
use std::{
convert::Infallible,
ops::{Deref, DerefMut},
};
pub use image::*;
use num::{
@ -6,15 +9,16 @@ use num::{
Zero,
};
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>>
where
Vec<P::Subpixel>: Deref<Target = [P::Subpixel]>,
P::Subpixel: ToBytes,
{
fn into_bytes(self) -> crate::Bytes {
fn into_data_bytes(self) -> crate::Bytes {
self.iter()
.flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec())
.collect()
@ -32,9 +36,9 @@ where
P::Subpixel: ToBytes + FromBytes,
<P::Subpixel as FromBytes>::Bytes: for<'a> TryFrom<&'a [u8]>,
{
type Error = ();
type Error = Infallible;
type Format = Dimensions;
fn try_from_bytes(
fn try_from_data_bytes(
bytes: crate::Bytes,
format: Self::Format,
crop: crate::Crop,
@ -70,7 +74,7 @@ where
.collect::<Vec<P::Subpixel>>(),
},
)
.ok_or(())
.ok_or_else(|| unreachable!())
}
}
@ -87,16 +91,67 @@ where
self
}
fn format() -> crate::Format {
crate::Format::Image
Format::Image
}
}
impl IntoDataBytes for DynamicImage {
fn into_bytes(self) -> crate::Bytes {
fn into_data_bytes(self) -> crate::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)]
mod tests {
#[cfg(test)]
@ -111,8 +166,8 @@ mod tests {
let image = RgbImage::new(0, 0);
assert_eq!(
Ok(image.clone()),
RgbImage::try_from_bytes(
image.into_bytes(),
RgbImage::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 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();
assert_eq!(
Ok(image.clone()),
RgbImage::try_from_bytes(
image.into_bytes(),
RgbImage::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 3,
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();
assert_eq!(
Ok(image.clone()),
RgbaImage::try_from_bytes(
image.into_bytes(),
RgbaImage::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 3,
height: 1
@ -165,8 +220,8 @@ mod tests {
.unwrap();
assert_eq!(
Ok(image.clone()),
ImageBuffer::<Rgb<u16>, Vec<u16>>::try_from_bytes(
image.into_bytes(),
ImageBuffer::<Rgb<u16>, Vec<u16>>::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 3,
height: 1
@ -186,8 +241,8 @@ mod tests {
.unwrap();
assert_eq!(
Ok(image.clone()),
ImageBuffer::<Rgb<i16>, Vec<i16>>::try_from_bytes(
image.into_bytes(),
ImageBuffer::<Rgb<i16>, Vec<i16>>::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 3,
height: 1
@ -207,8 +262,8 @@ mod tests {
.unwrap();
assert_eq!(
Ok(image.clone()),
Rgb32FImage::try_from_bytes(
image.into_bytes(),
Rgb32FImage::try_from_data_bytes(
image.into_data_bytes(),
Dimensions {
width: 3,
height: 1

View file

@ -5,7 +5,7 @@ pub mod txt;
pub(crate) type Bytes = Vec<u8>;
pub mod dynamic {
mod dynamic {
use std::{
fs::File,
io::{self, Read},
@ -64,30 +64,32 @@ pub mod dynamic {
}
}
use dynamic::*;
use std::convert::Infallible;
pub use dynamic::*;
pub trait Bendable: TryFromDataBytes + IntoDataBytes {
type Unit;
fn bend_into<T: Bendable>(
fn bend_into<T: TryFromDataBytes + IntoDataBytes>(
self,
format: <T as TryFromDataBytes>::Format,
crop: Crop,
) -> 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,
format: <Self as TryFromDataBytes>::Format,
crop: Crop,
) -> 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 format() -> Format;
}
pub trait IntoDataBytes: Sized {
fn into_bytes(self) -> Bytes;
fn into_data_bytes(self) -> Bytes;
}
#[derive(Default)]
@ -100,7 +102,31 @@ pub enum Crop {
pub trait TryFromDataBytes {
type Error;
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
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;
mod raw;
pub use raw::RawSamples;
mod simphonia;

View file

@ -17,7 +17,7 @@ impl<T> IntoDataBytes for RawSamples<T>
where
T: Sample + ToBytes,
{
fn into_bytes(self) -> crate::Bytes {
fn into_data_bytes(self) -> crate::Bytes {
self.as_ref()
.iter()
.flat_map(|subpixel| subpixel.to_ne_bytes().as_ref().to_vec())
@ -32,7 +32,7 @@ where
{
type Error = ();
type Format = ();
fn try_from_bytes(
fn try_from_data_bytes(
bytes: crate::Bytes,
_format: Self::Format,
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
repository.workspace = true
keywords.workspace = true
dependencies.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bingus = { path = "../bingus" }
clap = { version = "4.5.32", features = ["derive"] }