feature flags everywhere (warnings but no errors so far)
This commit is contained in:
parent
84a3b182ab
commit
51ab13b3ef
7 changed files with 186 additions and 25 deletions
|
@ -10,15 +10,15 @@ keywords.workspace = true
|
|||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[dependencies]
|
||||
image = { version = "0.25" }
|
||||
num = "0"
|
||||
image = { version = "0.25", optional = true }
|
||||
num = { version = "0", optional = true }
|
||||
rayon = { version = "1", optional = true }
|
||||
infer = "0"
|
||||
thiserror = "2"
|
||||
derive-new = "0"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
derive_wrapper = "0.1"
|
||||
symphonia = { version = "0.5", features = ["all"] }
|
||||
symphonia = { version = "0.5", features = ["all"], optional = true }
|
||||
printpdf = { version = "0.8.2", features = [
|
||||
"bmp",
|
||||
"dds",
|
||||
|
@ -32,10 +32,12 @@ printpdf = { version = "0.8.2", features = [
|
|||
"tiff",
|
||||
"js-sys",
|
||||
"webp",
|
||||
] }
|
||||
shiva = "1.4.9"
|
||||
anyhow = "1.0"
|
||||
font-kit = { version = "0.14.2", features = ["loader-freetype-default"] }
|
||||
], optional = true }
|
||||
shiva = { version = "1.4.9", optional = true }
|
||||
anyhow = { version = "1.0", optional = true }
|
||||
font-kit = { version = "0.14.2", features = [
|
||||
"loader-freetype-default",
|
||||
], optional = true }
|
||||
cfg-if = "1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -43,5 +45,20 @@ project-root = "0"
|
|||
pretty_assertions = "1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
rayon = ["image/rayon", "printpdf/rayon", "dep:rayon"]
|
||||
default = ["all-formats"]
|
||||
all-formats = ["binary", "documents", "fonts", "pictures", "music", "text"]
|
||||
|
||||
binary = []
|
||||
documents = ["shiva", "printpdf"]
|
||||
fonts = ["font-kit"]
|
||||
pictures = ["image"]
|
||||
music = ["symphonia", "dep:num"]
|
||||
text = []
|
||||
|
||||
shiva = ["dep:shiva", "dep:anyhow"]
|
||||
printpdf = ["dep:printpdf"]
|
||||
font-kit = ["dep:font-kit"]
|
||||
image = ["dep:image", "dep:num"]
|
||||
symphonia = ["dep:symphonia"]
|
||||
|
||||
rayon = ["image?/rayon", "printpdf?/rayon", "dep:rayon"]
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
pub use printpdf;
|
||||
mod pdf;
|
||||
#[cfg(feature = "shiva")]
|
||||
mod shiva;
|
||||
#[cfg(feature = "shiva")]
|
||||
pub use shiva::*;
|
||||
|
|
|
@ -64,6 +64,6 @@ impl Bendable for ShivaDocument {
|
|||
}
|
||||
|
||||
fn format() -> crate::Format {
|
||||
crate::Format::Text
|
||||
crate::Format::Doc
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
use cfg_if::cfg_if;
|
||||
use font_kit::error::FontLoadingError;
|
||||
pub use font_kit::font::Font;
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
@ -32,8 +33,21 @@ impl Bendable for Font {
|
|||
type Unit = u8;
|
||||
|
||||
fn map<F: Fn(Cow<Self::Unit>) -> Self::Unit + Sync>(self, f: F) -> Self {
|
||||
Self::try_from_data_bytes(self.into_data_bytes().map(f), (), Default::default())
|
||||
.expect("coudn't get font back from bytes after map")
|
||||
Self::try_from_data_bytes(
|
||||
{
|
||||
let bytes = self.into_data_bytes();
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "binary")] {
|
||||
bytes.map(f)
|
||||
} else {
|
||||
bytes.into_iter().map(|e| f(Cow::Owned(e))).collect()
|
||||
}
|
||||
}
|
||||
},
|
||||
(),
|
||||
Default::default(),
|
||||
)
|
||||
.expect("coudn't get font back from bytes after map")
|
||||
}
|
||||
|
||||
fn format() -> crate::Format {
|
||||
|
|
|
@ -1,52 +1,95 @@
|
|||
#[cfg(feature = "binary")]
|
||||
pub mod bin;
|
||||
#[cfg(feature = "documents")]
|
||||
pub mod doc;
|
||||
#[cfg(feature = "fonts")]
|
||||
pub mod fnt;
|
||||
#[cfg(feature = "pictures")]
|
||||
pub mod img;
|
||||
#[cfg(feature = "music")]
|
||||
pub mod snd;
|
||||
#[cfg(feature = "text")]
|
||||
pub mod txt;
|
||||
|
||||
pub type Bytes = Vec<u8>;
|
||||
|
||||
mod dynamic {
|
||||
#[cfg(feature = "text")]
|
||||
use std::string::FromUtf8Error;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
fs::File,
|
||||
io::{self, Read, Write},
|
||||
path::Path,
|
||||
string::FromUtf8Error,
|
||||
};
|
||||
|
||||
use super::{
|
||||
fnt::Font,
|
||||
img::{self, DynamicImage},
|
||||
snd::{self, Audio},
|
||||
txt::{ShivaDocument, Text},
|
||||
Bendable, Bytes, IntoDataBytes, TryFromDataBytes,
|
||||
};
|
||||
#[cfg(feature = "documents")]
|
||||
use super::doc::ShivaDocument;
|
||||
#[cfg(feature = "fonts")]
|
||||
use super::fnt::Font;
|
||||
#[cfg(feature = "pictures")]
|
||||
use super::img::{self, DynamicImage};
|
||||
#[cfg(feature = "music")]
|
||||
use super::snd::{self, Audio};
|
||||
#[cfg(feature = "text")]
|
||||
use super::txt::Text;
|
||||
use super::{Bendable, Bytes, IntoDataBytes, TryFromDataBytes};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use infer::MatcherType;
|
||||
#[cfg(feature = "documents")]
|
||||
use printpdf::PdfDocument;
|
||||
#[cfg(feature = "documents")]
|
||||
use shiva::core::{bytes, Document, DocumentType};
|
||||
use strum::EnumDiscriminants;
|
||||
use thiserror::Error;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "text")] {
|
||||
#[derive(EnumDiscriminants)]
|
||||
#[strum_discriminants(name(Format))]
|
||||
pub enum DynamicBendable<'a> {
|
||||
#[cfg(feature = "pictures")]
|
||||
Image(DynamicImage),
|
||||
#[cfg(feature = "binary")]
|
||||
Binary(Bytes),
|
||||
#[cfg(feature = "music")]
|
||||
Sound(Audio),
|
||||
#[cfg(feature = "text")]
|
||||
Text(Text<'a>),
|
||||
#[cfg(feature = "documents")]
|
||||
Doc(ShivaDocument),
|
||||
#[cfg(feature = "documents")]
|
||||
Archive(PdfDocument),
|
||||
Meta,
|
||||
#[cfg(feature = "fonts")]
|
||||
Font(Font),
|
||||
}} 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")]
|
||||
Doc(ShivaDocument),
|
||||
#[cfg(feature = "documents")]
|
||||
Archive(PdfDocument),
|
||||
Meta,
|
||||
#[cfg(feature = "fonts")]
|
||||
Font(Font),
|
||||
}
|
||||
}}
|
||||
|
||||
#[cfg(feature = "shiva")]
|
||||
#[derive(Debug, Error)]
|
||||
#[error("extension is unknown by Shiva")]
|
||||
pub struct ShivaUnknownExtensionError;
|
||||
|
||||
#[cfg(feature = "shiva")]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ShivaError {
|
||||
#[error("{0}")]
|
||||
|
@ -59,14 +102,19 @@ mod dynamic {
|
|||
pub enum OpenError {
|
||||
#[error("io: {0}")]
|
||||
Io(#[from] io::Error),
|
||||
#[cfg(feature = "pictures")]
|
||||
#[error("image: {0}")]
|
||||
Image(#[from] img::ImageError),
|
||||
#[cfg(feature = "music")]
|
||||
#[error("audio: {0}")]
|
||||
Audio(#[from] snd::AudioOpenError),
|
||||
#[cfg(feature = "documents")]
|
||||
#[error("pdf: {0}")]
|
||||
Pdf(String),
|
||||
#[cfg(feature = "text")]
|
||||
#[error("text: {0}")]
|
||||
Text(#[from] FromUtf8Error),
|
||||
#[cfg(feature = "documents")]
|
||||
#[error("document: {0}")]
|
||||
Document(#[from] ShivaError),
|
||||
}
|
||||
|
@ -102,7 +150,13 @@ mod dynamic {
|
|||
fn map<F: Fn(Cow<Self::Unit>) -> Self::Unit + Sync>(mut self, f: F) -> Self {
|
||||
let mut bytes = Vec::new();
|
||||
self.read_to_end(&mut bytes).expect("couldn't read file");
|
||||
self.write_all(&bytes.map(f)).expect("couldn't write file");
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "binary")] {
|
||||
self.write_all(&bytes.map(f)).expect("couldn't write file");
|
||||
} else {
|
||||
self.write_all(&bytes.into_iter().map(|e| f(Cow::Owned(e))).collect::<Vec<u8>>()).expect("couldn't write file");
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -111,6 +165,8 @@ mod dynamic {
|
|||
}
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "text")] {
|
||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Option<DynamicBendable<'static>>, OpenError> {
|
||||
use MatcherType::*;
|
||||
infer::get_from_path(&path)?
|
||||
|
@ -118,8 +174,11 @@ mod dynamic {
|
|||
.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)?
|
||||
|
@ -130,6 +189,7 @@ mod dynamic {
|
|||
)
|
||||
.map_err(OpenError::Pdf)?,
|
||||
),
|
||||
#[cfg(feature = "documents")]
|
||||
Archive => {
|
||||
let document_type = DocumentType::from_extension(extension)
|
||||
.ok_or(ShivaUnknownExtensionError)
|
||||
|
@ -145,7 +205,9 @@ mod dynamic {
|
|||
}
|
||||
Book => todo!(),
|
||||
Doc => todo!(),
|
||||
#[cfg(feature = "fonts")]
|
||||
Font => todo!(),
|
||||
#[cfg(feature = "text")]
|
||||
Text => DynamicBendable::Text(crate::txt::Text::try_from_data_bytes(
|
||||
File::open(path)?
|
||||
.bytes()
|
||||
|
@ -153,16 +215,80 @@ mod dynamic {
|
|||
(),
|
||||
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 available to open this thing"),
|
||||
})
|
||||
},
|
||||
)
|
||||
.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)?,
|
||||
),
|
||||
#[cfg(feature = "documents")]
|
||||
Archive => {
|
||||
let document_type = DocumentType::from_extension(extension)
|
||||
.ok_or(ShivaUnknownExtensionError)
|
||||
.map_err(ShivaError::UnknownExtension)?;
|
||||
DynamicBendable::Doc(ShivaDocument::new(
|
||||
Document::parse(
|
||||
&bytes::Bytes::from(std::fs::read(path)?),
|
||||
document_type,
|
||||
)
|
||||
.map_err(ShivaError::Anyhow)?,
|
||||
document_type,
|
||||
))
|
||||
}
|
||||
Book => todo!(),
|
||||
Doc => todo!(),
|
||||
#[cfg(feature = "fonts")]
|
||||
Font => todo!(),
|
||||
#[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
|
||||
}),
|
||||
_ => unimplemented!("no format available to open this thing"),
|
||||
})
|
||||
},
|
||||
)
|
||||
.transpose()
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
use std::{borrow::Cow, convert::Infallible};
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
mod bare;
|
||||
pub use bare::*;
|
||||
mod shiva;
|
||||
pub use shiva::*;
|
||||
|
|
|
@ -2,8 +2,10 @@ use std::path::PathBuf;
|
|||
|
||||
use clap::Parser;
|
||||
|
||||
/// CLI from the Bent project
|
||||
#[derive(Parser)]
|
||||
pub(super) struct Cli {
|
||||
pub(super) input_file: PathBuf,
|
||||
pub(super) output_file: PathBuf,
|
||||
/// Input file or standard input.
|
||||
pub(super) input: PathBuf,
|
||||
pub(super) output: PathBuf,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue