relax trait requirements, rename failable methods with 'try'
This commit is contained in:
parent
58cf13a564
commit
f4e8f7c276
8 changed files with 163 additions and 33 deletions
|
@ -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"] }
|
||||||
|
|
|
@ -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,
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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!())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
42
bingus/src/snd/simphonia.rs
Normal file
42
bingus/src/snd/simphonia.rs
Normal 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!()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"] }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue