remove duplicate code, open from any Read sources
This commit is contained in:
parent
130a75d0ca
commit
53bdd265b3
3 changed files with 94 additions and 164 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bingus"
|
name = "bingus"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
|
|
|
@ -19,7 +19,7 @@ mod dynamic {
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, Read, Write},
|
io::{self, Cursor, Read, Write},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@ mod dynamic {
|
||||||
#[cfg(feature = "text")]
|
#[cfg(feature = "text")]
|
||||||
use super::txt::Text;
|
use super::txt::Text;
|
||||||
use super::{Bendable, Bytes, IntoDataBytes, TryFromDataBytes};
|
use super::{Bendable, Bytes, IntoDataBytes, TryFromDataBytes};
|
||||||
|
#[cfg(not(feature = "text"))]
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use cfg_if::cfg_if;
|
use cfg_if::cfg_if;
|
||||||
#[cfg(feature = "fonts")]
|
#[cfg(feature = "fonts")]
|
||||||
|
@ -46,8 +48,6 @@ mod dynamic {
|
||||||
use strum::EnumDiscriminants;
|
use strum::EnumDiscriminants;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(feature = "text")] {
|
|
||||||
#[derive(EnumDiscriminants)]
|
#[derive(EnumDiscriminants)]
|
||||||
#[strum_discriminants(name(Format))]
|
#[strum_discriminants(name(Format))]
|
||||||
pub enum DynamicBendable<'a> {
|
pub enum DynamicBendable<'a> {
|
||||||
|
@ -59,23 +59,8 @@ mod dynamic {
|
||||||
Sound(Audio),
|
Sound(Audio),
|
||||||
#[cfg(feature = "text")]
|
#[cfg(feature = "text")]
|
||||||
Text(Text<'a>),
|
Text(Text<'a>),
|
||||||
#[cfg(feature = "documents")]
|
#[cfg(not(feature = "text"))]
|
||||||
Doc(ShivaDocument),
|
Phantom(PhantomData<&'a ()>),
|
||||||
#[cfg(feature = "documents")]
|
|
||||||
Archive(PdfDocument),
|
|
||||||
Meta,
|
|
||||||
#[cfg(feature = "fonts")]
|
|
||||||
Font(FontKitFont),
|
|
||||||
}} else {
|
|
||||||
#[derive(EnumDiscriminants)]
|
|
||||||
#[strum_discriminants(name(Format))]
|
|
||||||
pub enum DynamicBendable {
|
|
||||||
#[cfg(feature = "pictures")]
|
|
||||||
Image(DynamicImage),
|
|
||||||
#[cfg(feature = "binary")]
|
|
||||||
Binary(Bytes),
|
|
||||||
#[cfg(feature = "music")]
|
|
||||||
Sound(Audio),
|
|
||||||
#[cfg(feature = "documents")]
|
#[cfg(feature = "documents")]
|
||||||
Doc(ShivaDocument),
|
Doc(ShivaDocument),
|
||||||
#[cfg(feature = "documents")]
|
#[cfg(feature = "documents")]
|
||||||
|
@ -84,7 +69,6 @@ mod dynamic {
|
||||||
#[cfg(feature = "fonts")]
|
#[cfg(feature = "fonts")]
|
||||||
Font(FontKitFont),
|
Font(FontKitFont),
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
|
|
||||||
#[cfg(feature = "shiva")]
|
#[cfg(feature = "shiva")]
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
@ -170,132 +154,75 @@ mod dynamic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_if! {
|
pub type DynamicResult = Result<Option<DynamicBendable<'static>>, OpenError>;
|
||||||
if #[cfg(feature = "text")] {
|
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Option<DynamicBendable<'static>>, OpenError> {
|
fn guess(t: Option<infer::Type>, bytes: Bytes) -> DynamicResult {
|
||||||
use MatcherType::*;
|
use MatcherType::*;
|
||||||
infer::get_from_path(&path)?
|
t.map(|t| (t.matcher_type(), t.extension()))
|
||||||
.map(|t| (t.matcher_type(), t.extension()))
|
.map(
|
||||||
.map(
|
|(matcher, extension)| -> Result<DynamicBendable, OpenError> {
|
||||||
|(matcher, extension)| -> Result<DynamicBendable, OpenError> {
|
Ok(match matcher {
|
||||||
Ok(match matcher {
|
#[cfg(feature = "pictures")]
|
||||||
#[cfg(feature = "pictures")]
|
Image => DynamicBendable::Image(img::load_from_memory(&bytes)?),
|
||||||
Image => DynamicBendable::Image(img::open(path)?),
|
#[cfg(feature = "music")]
|
||||||
#[cfg(feature = "music")]
|
Audio => DynamicBendable::Sound(crate::snd::Audio::open(Cursor::new(bytes), None)?),
|
||||||
Audio => DynamicBendable::Sound(crate::snd::Audio::open(path)?),
|
#[cfg(feature = "documents")]
|
||||||
#[cfg(feature = "documents")]
|
Archive if extension == "pdf" => DynamicBendable::Archive(
|
||||||
Archive if extension == "pdf" => DynamicBendable::Archive(
|
PdfDocument::try_from_data_bytes(
|
||||||
PdfDocument::try_from_data_bytes(
|
bytes,
|
||||||
File::open(path)?
|
(),
|
||||||
.bytes()
|
Default::default(),
|
||||||
.collect::<Result<Bytes, io::Error>>()?,
|
)
|
||||||
(),
|
.map_err(OpenError::Pdf)?,
|
||||||
Default::default(),
|
),
|
||||||
)
|
#[cfg(feature = "documents")]
|
||||||
.map_err(OpenError::Pdf)?,
|
Archive | Doc => {
|
||||||
),
|
let document_type = DocumentType::from_extension(extension)
|
||||||
#[cfg(feature = "documents")]
|
.ok_or(ShivaUnknownExtensionError)
|
||||||
Archive | Doc => {
|
.map_err(ShivaError::UnknownExtension)?;
|
||||||
let document_type = DocumentType::from_extension(extension)
|
DynamicBendable::Doc(ShivaDocument::new(
|
||||||
.ok_or(ShivaUnknownExtensionError)
|
Document::parse(
|
||||||
.map_err(ShivaError::UnknownExtension)?;
|
&bytes::Bytes::from(bytes),
|
||||||
DynamicBendable::Doc(ShivaDocument::new(
|
|
||||||
Document::parse(
|
|
||||||
&bytes::Bytes::from(std::fs::read(path)?),
|
|
||||||
document_type,
|
|
||||||
)
|
|
||||||
.map_err(ShivaError::Anyhow)?,
|
|
||||||
document_type,
|
document_type,
|
||||||
))
|
|
||||||
}
|
|
||||||
#[cfg(feature = "fonts")]
|
|
||||||
Font => DynamicBendable::Font(FontKitFont::try_from_data_bytes(
|
|
||||||
File::open(path)?
|
|
||||||
.bytes()
|
|
||||||
.collect::<Result<Bytes, io::Error>>()?,
|
|
||||||
(),
|
|
||||||
Default::default(),
|
|
||||||
)?),
|
|
||||||
#[cfg(feature = "text")]
|
|
||||||
Text => DynamicBendable::Text(crate::txt::Text::try_from_data_bytes(
|
|
||||||
File::open(path)?
|
|
||||||
.bytes()
|
|
||||||
.collect::<Result<Bytes, io::Error>>()?,
|
|
||||||
(),
|
|
||||||
Default::default(),
|
|
||||||
)?),
|
|
||||||
#[cfg(feature = "binary")]
|
|
||||||
_ => DynamicBendable::Binary({
|
|
||||||
let mut buf = Vec::new();
|
|
||||||
File::open(path)?.read_to_end(&mut buf)?;
|
|
||||||
buf
|
|
||||||
}),
|
|
||||||
#[cfg(not(feature = "binary"))]
|
|
||||||
_ => unimplemented!("no format reader available to open this thing (turn on the 'binary' feature to default to binary data)"),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.transpose()
|
|
||||||
}} else {
|
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Option<DynamicBendable>, OpenError> {
|
|
||||||
use MatcherType::*;
|
|
||||||
infer::get_from_path(&path)?
|
|
||||||
.map(|t| (t.matcher_type(), t.extension()))
|
|
||||||
.map(
|
|
||||||
|(matcher, extension)| -> Result<DynamicBendable, OpenError> {
|
|
||||||
Ok(match matcher {
|
|
||||||
#[cfg(feature = "pictures")]
|
|
||||||
Image => DynamicBendable::Image(img::open(path)?),
|
|
||||||
#[cfg(feature = "music")]
|
|
||||||
Audio => DynamicBendable::Sound(crate::snd::Audio::open(path)?),
|
|
||||||
#[cfg(feature = "documents")]
|
|
||||||
Archive if extension == "pdf" => DynamicBendable::Archive(
|
|
||||||
PdfDocument::try_from_data_bytes(
|
|
||||||
File::open(path)?
|
|
||||||
.bytes()
|
|
||||||
.collect::<Result<Bytes, io::Error>>()?,
|
|
||||||
(),
|
|
||||||
Default::default(),
|
|
||||||
)
|
)
|
||||||
.map_err(OpenError::Pdf)?,
|
.map_err(ShivaError::Anyhow)?,
|
||||||
),
|
document_type,
|
||||||
#[cfg(feature = "documents")]
|
))
|
||||||
Archive | Doc => {
|
}
|
||||||
let document_type = DocumentType::from_extension(extension)
|
#[cfg(feature = "fonts")]
|
||||||
.ok_or(ShivaUnknownExtensionError)
|
Font => DynamicBendable::Font(FontKitFont::try_from_data_bytes(
|
||||||
.map_err(ShivaError::UnknownExtension)?;
|
bytes,
|
||||||
DynamicBendable::Doc(ShivaDocument::new(
|
(),
|
||||||
Document::parse(
|
Default::default(),
|
||||||
&bytes::Bytes::from(std::fs::read(path)?),
|
)?),
|
||||||
document_type,
|
#[cfg(feature = "text")]
|
||||||
)
|
Text => DynamicBendable::Text(crate::txt::Text::try_from_data_bytes(
|
||||||
.map_err(ShivaError::Anyhow)?,
|
bytes,
|
||||||
document_type,
|
(),
|
||||||
))
|
Default::default(),
|
||||||
}
|
)?),
|
||||||
#[cfg(feature = "fonts")]
|
#[cfg(feature = "binary")]
|
||||||
Font => todo!(),
|
_ => DynamicBendable::Binary(bytes),
|
||||||
#[cfg(feature = "text")]
|
#[cfg(not(feature = "binary"))]
|
||||||
Text => DynamicBendable::Text(crate::txt::Text::try_from_data_bytes(
|
_ => unimplemented!("no format reader available to open this thing (turn on the 'binary' feature to default to binary data)"),
|
||||||
File::open(path)?
|
})
|
||||||
.bytes()
|
},
|
||||||
.collect::<Result<Bytes, io::Error>>()?,
|
)
|
||||||
(),
|
.transpose()
|
||||||
Default::default(),
|
}
|
||||||
)?),
|
|
||||||
#[cfg(feature = "binary")]
|
pub fn open_file(path: impl AsRef<Path>) -> DynamicResult {
|
||||||
_ => DynamicBendable::Binary({
|
open(&mut File::open(path)?)
|
||||||
let mut buf = Vec::new();
|
}
|
||||||
File::open(path)?.read_to_end(&mut buf)?;
|
|
||||||
buf
|
pub fn open(source: &mut impl Read) -> DynamicResult {
|
||||||
}),
|
let contents = {
|
||||||
_ => unimplemented!("no format available to open this thing"),
|
let mut c = Vec::new();
|
||||||
})
|
source.read_to_end(&mut c)?;
|
||||||
},
|
c
|
||||||
)
|
};
|
||||||
.transpose()
|
guess(infer::get(&contents), contents)
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::{borrow::Cow, convert::Infallible};
|
use std::{borrow::Cow, convert::Infallible};
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use std::{
|
use std::io::{self, Read};
|
||||||
fs::File,
|
|
||||||
io::{self, Read},
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use symphonia::{
|
use symphonia::{
|
||||||
|
@ -11,7 +7,7 @@ use symphonia::{
|
||||||
codecs::{Decoder, CODEC_TYPE_NULL},
|
codecs::{Decoder, CODEC_TYPE_NULL},
|
||||||
conv::FromSample,
|
conv::FromSample,
|
||||||
formats::FormatReader,
|
formats::FormatReader,
|
||||||
io::MediaSourceStream,
|
io::{MediaSource, MediaSourceStream},
|
||||||
probe::Hint,
|
probe::Hint,
|
||||||
sample::{i24, u24},
|
sample::{i24, u24},
|
||||||
},
|
},
|
||||||
|
@ -51,19 +47,22 @@ impl PartialEq for AudioOpenError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Audio {
|
impl Audio {
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Audio, AudioOpenError> {
|
pub fn open(
|
||||||
|
source: impl MediaSource + 'static,
|
||||||
|
extension: Option<&str>,
|
||||||
|
) -> Result<Audio, AudioOpenError> {
|
||||||
let registry = default::get_codecs();
|
let registry = default::get_codecs();
|
||||||
let probe = default::get_probe();
|
let probe = default::get_probe();
|
||||||
let mediasource = File::open(path.as_ref())?;
|
let mss = MediaSourceStream::new(Box::new(source), Default::default());
|
||||||
let mss = MediaSourceStream::new(Box::new(mediasource), Default::default());
|
|
||||||
let reader = probe
|
let reader = probe
|
||||||
.format(
|
.format(
|
||||||
Hint::new().with_extension(
|
&{
|
||||||
path.as_ref()
|
let mut hint = Hint::new();
|
||||||
.extension()
|
if let Some(e) = extension {
|
||||||
.and_then(|os_str| os_str.to_str())
|
hint.with_extension(e);
|
||||||
.unwrap_or("mp3"),
|
}
|
||||||
),
|
hint
|
||||||
|
},
|
||||||
mss,
|
mss,
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
|
@ -161,6 +160,8 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::fs::File;
|
||||||
|
|
||||||
use project_root::get_project_root;
|
use project_root::get_project_root;
|
||||||
|
|
||||||
use crate::IntoDataBytes;
|
use crate::IntoDataBytes;
|
||||||
|
@ -171,12 +172,14 @@ mod tests {
|
||||||
fn open_sample_file() {
|
fn open_sample_file() {
|
||||||
let original =
|
let original =
|
||||||
&include_bytes!("../../../testing material/sound/sample-3s.mp3")[52079 - 51826..];
|
&include_bytes!("../../../testing material/sound/sample-3s.mp3")[52079 - 51826..];
|
||||||
|
let path = get_project_root()
|
||||||
|
.expect("can't find project root!")
|
||||||
|
.join("testing material")
|
||||||
|
.join("sound")
|
||||||
|
.join("sample-3s.mp3");
|
||||||
let result = Audio::open(
|
let result = Audio::open(
|
||||||
get_project_root()
|
File::open(&path).expect("can't find test file!"),
|
||||||
.expect("can't find project root!")
|
path.extension().and_then(|s| s.to_str()),
|
||||||
.join("testing material")
|
|
||||||
.join("sound")
|
|
||||||
.join("sample-3s.mp3"),
|
|
||||||
)
|
)
|
||||||
.map(|audio| audio.into_data_bytes());
|
.map(|audio| audio.into_data_bytes());
|
||||||
dbg!(original.len());
|
dbg!(original.len());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue