Skip to content

Commit

Permalink
Change the interface
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanUkhov committed Feb 28, 2025
1 parent 66ba9dd commit 792b7f9
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 148 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ build = "build.rs"
[features]
default = ["version1", "version2"]

binary = ["arguments", "version1", "version2"]
binary = ["arguments"]
version1 = []
version2 = []

Expand Down
94 changes: 58 additions & 36 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,73 @@
use std::fs::{read, write};
use std::path::PathBuf;

#[allow(unused_variables)]
fn main() {
let arguments::Arguments {
options, orphans, ..
} = arguments::parse(std::env::args()).expect("failed to parse arguments");
#[allow(clippy::get_first)]
let source = match orphans.get(0) {
Some(value) => PathBuf::from(value),
_ => {
eprintln!("Error: a source should be given.");
std::process::exit(1);
}
_ => usage(),
};
let destination = match orphans.get(1) {
Some(value) => PathBuf::from(value),
_ => {
eprintln!("Error: a destination should be given.");
std::process::exit(1);
}
_ => usage(),
};
let source_extension = source.extension().and_then(|value| value.to_str());
let destination_extension = destination.extension().and_then(|value| value.to_str());
if source_extension
.map(|value| value == "woff")
.unwrap_or(false)
|| destination_extension
.map(|value| value == "woff")
.unwrap_or(false)
{
woff::version1::convert(source, destination).expect("failed to transform");
} else if source_extension
.map(|value| value == "woff2")
.unwrap_or(false)
|| destination_extension
.map(|value| value == "woff2")
.unwrap_or(false)
{
woff::version2::convert(
source,
destination,
options.get::<String>("metadata"),
options.get::<usize>("quality"),
options.get::<bool>("transform"),
)
.expect("failed to transform");
} else {
eprintln!("Error: one file should end with either .woff or .woff2.");
std::process::exit(1);
#[allow(unused_mut)]
let mut data = read(&source).expect("failed to read the source");
match (
source.extension().and_then(|value| value.to_str()),
destination.extension().and_then(|value| value.to_str()),
) {
#[cfg(feature = "version1")]
(_, Some("woff")) => {
data = woff::version1::compress(
&data,
options.get::<usize>("major").unwrap_or(1),
options.get::<usize>("minor").unwrap_or(0),
)
.expect("failed to compress");
}
#[cfg(feature = "version1")]
(Some("woff"), _) => {
data = woff::version1::decompress(&data).expect("failed to decompress");
}
#[cfg(feature = "version2")]
(_, Some("woff2")) => {
data = woff::version2::compress(
&data,
options.get::<usize>("quality").unwrap_or(8),
options.get::<String>("metadata").unwrap_or_default(),
options.get::<bool>("transform").unwrap_or(true),
)
.expect("failed to compress");
}
#[cfg(feature = "version2")]
(Some("woff2"), _) => {
data = woff::version2::decompress(&data).expect("failed to decompress");
}
_ => usage(),
}
#[allow(unreachable_code)]
write(destination, data).expect("failed to write to the destination");
}

fn usage() -> ! {
eprintln!(
r#"Usage: <source> <destination> [options]
Either the source or destination should end with either .woff or .woff2.
Options for WOFF:
--major <number>
--minor <number>
Options for WOFF2:
--quality <number>
--metadata <string>
--no-transform"#
);
std::process::exit(1);
}
76 changes: 31 additions & 45 deletions src/version1/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@
mod ffi;

use std::io::{Error, Result};
use std::path::Path;

/// Compress.
pub fn compress(data: &[u8]) -> Option<Vec<u8>> {
pub fn compress(data: &[u8], major_version: usize, minor_version: usize) -> Option<Vec<u8>> {
let mut size = 0;
let mut status = 0;
let data = unsafe {
ffi::woffEncode(
data.as_ptr() as _,
data.len() as _,
1,
0,
major_version as _,
minor_version as _,
&mut size,
&mut status,
)
Expand All @@ -35,29 +32,6 @@ pub fn decompress(data: &[u8]) -> Option<Vec<u8>> {
finalize(data, size, status)
}

/// Compress or decompress.
pub fn convert<T: AsRef<Path>>(source: T, destination: T) -> Result<()> {
let data = std::fs::read(source)?;
let destination = destination.as_ref();
let data = if destination
.extension()
.and_then(|value| value.to_str())
.map(|value| value == "woff")
.unwrap_or(false)
{
match compress(&data) {
Some(data) => data,
_ => return Err(Error::other("failed to compress")),
}
} else {
match decompress(&data) {
Some(data) => data,
_ => return Err(Error::other("failed to decompress")),
}
};
std::fs::write(destination, data)
}

fn finalize(data: *const u8, size: u32, status: u32) -> Option<Vec<u8>> {
if !data.is_null() && status == 0 {
let mut buffer = Vec::with_capacity(size as _);
Expand All @@ -79,31 +53,43 @@ fn finalize(data: *const u8, size: u32, status: u32) -> Option<Vec<u8>> {

#[cfg(test)]
mod tests {
use std::fs::{read, write};

macro_rules! ok(($result:expr) => ($result.unwrap()));

#[test]
fn otf() {
super::convert(
"tests/fixtures/Roboto-Regular.otf",
"tests/fixtures/Roboto-Regular.otf.woff",
)
.unwrap();
super::convert(
ok!(write(
"tests/fixtures/Roboto-Regular.otf.woff",
ok!(super::compress(
&ok!(read("tests/fixtures/Roboto-Regular.otf")),
Default::default(),
Default::default(),
)),
));
ok!(write(
"tests/fixtures/Roboto-Regular.otf",
)
.unwrap();
ok!(super::decompress(&ok!(read(
"tests/fixtures/Roboto-Regular.otf.woff"
)))),
));
}

#[test]
fn ttf() {
super::convert(
"tests/fixtures/Roboto-Regular.ttf",
"tests/fixtures/Roboto-Regular.ttf.woff",
)
.unwrap();
super::convert(
ok!(write(
"tests/fixtures/Roboto-Regular.ttf.woff",
ok!(super::compress(
&ok!(read("tests/fixtures/Roboto-Regular.ttf")),
Default::default(),
Default::default(),
)),
));
ok!(write(
"tests/fixtures/Roboto-Regular.ttf",
)
.unwrap();
ok!(super::decompress(&ok!(read(
"tests/fixtures/Roboto-Regular.ttf.woff"
)))),
));
}
}
99 changes: 33 additions & 66 deletions src/version2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
mod ffi;

use std::io::{Error, Result};
use std::path::Path;

/// Compress.
pub fn compress(data: &[u8], metadata: String, quality: usize, transform: bool) -> Option<Vec<u8>> {
pub fn compress(data: &[u8], quality: usize, metadata: String, transform: bool) -> Option<Vec<u8>> {
let metadata_length = metadata.len();
let metadata = match std::ffi::CString::new(metadata) {
Ok(metadata) => metadata,
Expand Down Expand Up @@ -63,79 +60,49 @@ pub fn decompress(data: &[u8]) -> Option<Vec<u8>> {
buffer.into()
}

/// Compress or decompress.
pub fn convert<T: AsRef<Path>>(
source: T,
destination: T,
metadata: Option<String>,
quality: Option<usize>,
transform: Option<bool>,
) -> Result<()> {
let data = std::fs::read(source)?;
let destination = destination.as_ref();
let data = if destination
.extension()
.and_then(|value| value.to_str())
.map(|value| value == "woff2")
.unwrap_or(false)
{
match compress(
&data,
metadata.unwrap_or_default(),
quality.unwrap_or(8),
transform.unwrap_or(true),
) {
Some(data) => data,
_ => return Err(Error::other("failed to compress")),
}
} else {
match decompress(&data) {
Some(data) => data,
_ => return Err(Error::other("failed to decompress")),
}
};
std::fs::write(destination, data)
}

#[cfg(test)]
mod tests {
use std::fs::{read, write};

const DEFAULT_QUALITY: usize = 8;

macro_rules! ok(($result:expr) => ($result.unwrap()));

#[test]
fn otf() {
super::convert(
"tests/fixtures/Roboto-Regular.otf",
"tests/fixtures/Roboto-Regular.otf.woff2",
None,
None,
None,
)
.unwrap();
super::convert(
ok!(write(
"tests/fixtures/Roboto-Regular.otf.woff2",
ok!(super::compress(
&ok!(read("tests/fixtures/Roboto-Regular.otf")),
DEFAULT_QUALITY,
Default::default(),
Default::default(),
)),
));
ok!(write(
"tests/fixtures/Roboto-Regular.otf",
None,
None,
None,
)
.unwrap();
ok!(super::decompress(&ok!(read(
"tests/fixtures/Roboto-Regular.otf.woff2"
)))),
));
}

#[test]
fn ttf() {
super::convert(
"tests/fixtures/Roboto-Regular.ttf",
"tests/fixtures/Roboto-Regular.ttf.woff2",
None,
None,
None,
)
.unwrap();
super::convert(
ok!(write(
"tests/fixtures/Roboto-Regular.ttf.woff2",
ok!(super::compress(
&ok!(read("tests/fixtures/Roboto-Regular.ttf")),
DEFAULT_QUALITY,
Default::default(),
Default::default(),
)),
));
ok!(write(
"tests/fixtures/Roboto-Regular.ttf",
None,
None,
None,
)
.unwrap();
ok!(super::decompress(&ok!(read(
"tests/fixtures/Roboto-Regular.ttf.woff2"
)))),
));
}
}

0 comments on commit 792b7f9

Please sign in to comment.