Skip to content

Commit e542b22

Browse files
committed
Change the interface
1 parent 66ba9dd commit e542b22

File tree

4 files changed

+134
-151
lines changed

4 files changed

+134
-151
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ build = "build.rs"
2626
[features]
2727
default = ["version1", "version2"]
2828

29-
binary = ["arguments", "version1", "version2"]
29+
binary = ["arguments"]
3030
version1 = []
3131
version2 = []
3232

src/main.rs

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,73 @@
1+
use std::fs::{read, write};
12
use std::path::PathBuf;
23

4+
#[allow(unused_variables)]
35
fn main() {
46
let arguments::Arguments {
57
options, orphans, ..
68
} = arguments::parse(std::env::args()).expect("failed to parse arguments");
79
#[allow(clippy::get_first)]
810
let source = match orphans.get(0) {
911
Some(value) => PathBuf::from(value),
10-
_ => {
11-
eprintln!("Error: a source should be given.");
12-
std::process::exit(1);
13-
}
12+
_ => usage(),
1413
};
1514
let destination = match orphans.get(1) {
1615
Some(value) => PathBuf::from(value),
17-
_ => {
18-
eprintln!("Error: a destination should be given.");
19-
std::process::exit(1);
20-
}
16+
_ => usage(),
2117
};
22-
let source_extension = source.extension().and_then(|value| value.to_str());
23-
let destination_extension = destination.extension().and_then(|value| value.to_str());
24-
if source_extension
25-
.map(|value| value == "woff")
26-
.unwrap_or(false)
27-
|| destination_extension
28-
.map(|value| value == "woff")
29-
.unwrap_or(false)
30-
{
31-
woff::version1::convert(source, destination).expect("failed to transform");
32-
} else if source_extension
33-
.map(|value| value == "woff2")
34-
.unwrap_or(false)
35-
|| destination_extension
36-
.map(|value| value == "woff2")
37-
.unwrap_or(false)
38-
{
39-
woff::version2::convert(
40-
source,
41-
destination,
42-
options.get::<String>("metadata"),
43-
options.get::<usize>("quality"),
44-
options.get::<bool>("transform"),
45-
)
46-
.expect("failed to transform");
47-
} else {
48-
eprintln!("Error: one file should end with either .woff or .woff2.");
49-
std::process::exit(1);
18+
#[allow(unused_mut)]
19+
let mut data = read(&source).expect("failed to read the source");
20+
match (
21+
source.extension().and_then(|value| value.to_str()),
22+
destination.extension().and_then(|value| value.to_str()),
23+
) {
24+
#[cfg(feature = "version1")]
25+
(_, Some("woff")) => {
26+
data = woff::version1::compress(
27+
&data,
28+
options.get::<usize>("major").unwrap_or(1),
29+
options.get::<usize>("minor").unwrap_or(0),
30+
)
31+
.expect("failed to compress");
32+
}
33+
#[cfg(feature = "version1")]
34+
(Some("woff"), _) => {
35+
data = woff::version1::decompress(&data).expect("failed to decompress");
36+
}
37+
#[cfg(feature = "version2")]
38+
(_, Some("woff2")) => {
39+
data = woff::version2::compress(
40+
&data,
41+
options.get::<usize>("quality").unwrap_or(8),
42+
options.get::<String>("metadata").unwrap_or_default(),
43+
options.get::<bool>("transform").unwrap_or(true),
44+
)
45+
.expect("failed to compress");
46+
}
47+
#[cfg(feature = "version2")]
48+
(Some("woff2"), _) => {
49+
data = woff::version2::decompress(&data).expect("failed to decompress");
50+
}
51+
_ => usage(),
5052
}
53+
#[allow(unreachable_code)]
54+
write(destination, data).expect("failed to write to the destination");
55+
}
56+
57+
fn usage() -> ! {
58+
eprintln!(
59+
r#"Usage: <source> <destination> [options]
60+
61+
Either the source or destination should end with either .woff or .woff2.
62+
63+
Options for WOFF:
64+
--major <number>
65+
--minor <number>
66+
67+
Options for WOFF2:
68+
--quality <number>
69+
--metadata <string>
70+
--no-transform"#
71+
);
72+
std::process::exit(1);
5173
}

src/version1/mod.rs

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@
44
55
mod ffi;
66

7-
use std::io::{Error, Result};
8-
use std::path::Path;
9-
107
/// Compress.
11-
pub fn compress(data: &[u8]) -> Option<Vec<u8>> {
8+
pub fn compress(data: &[u8], major_version: usize, minor_version: usize) -> Option<Vec<u8>> {
129
let mut size = 0;
1310
let mut status = 0;
1411
let data = unsafe {
1512
ffi::woffEncode(
1613
data.as_ptr() as _,
1714
data.len() as _,
18-
1,
19-
0,
15+
major_version as _,
16+
minor_version as _,
2017
&mut size,
2118
&mut status,
2219
)
@@ -35,29 +32,6 @@ pub fn decompress(data: &[u8]) -> Option<Vec<u8>> {
3532
finalize(data, size, status)
3633
}
3734

38-
/// Compress or decompress.
39-
pub fn convert<T: AsRef<Path>>(source: T, destination: T) -> Result<()> {
40-
let data = std::fs::read(source)?;
41-
let destination = destination.as_ref();
42-
let data = if destination
43-
.extension()
44-
.and_then(|value| value.to_str())
45-
.map(|value| value == "woff")
46-
.unwrap_or(false)
47-
{
48-
match compress(&data) {
49-
Some(data) => data,
50-
_ => return Err(Error::other("failed to compress")),
51-
}
52-
} else {
53-
match decompress(&data) {
54-
Some(data) => data,
55-
_ => return Err(Error::other("failed to decompress")),
56-
}
57-
};
58-
std::fs::write(destination, data)
59-
}
60-
6135
fn finalize(data: *const u8, size: u32, status: u32) -> Option<Vec<u8>> {
6236
if !data.is_null() && status == 0 {
6337
let mut buffer = Vec::with_capacity(size as _);
@@ -79,31 +53,46 @@ fn finalize(data: *const u8, size: u32, status: u32) -> Option<Vec<u8>> {
7953

8054
#[cfg(test)]
8155
mod tests {
56+
use std::fs::{read, write};
57+
58+
const DEFAULT_MAJOR: usize = 1;
59+
const DEFAULT_MINOR: usize = 0;
60+
61+
macro_rules! ok(($result:expr) => ($result.unwrap()));
62+
8263
#[test]
8364
fn otf() {
84-
super::convert(
85-
"tests/fixtures/Roboto-Regular.otf",
86-
"tests/fixtures/Roboto-Regular.otf.woff",
87-
)
88-
.unwrap();
89-
super::convert(
65+
ok!(write(
9066
"tests/fixtures/Roboto-Regular.otf.woff",
67+
ok!(super::compress(
68+
&ok!(read("tests/fixtures/Roboto-Regular.otf")),
69+
DEFAULT_MAJOR,
70+
DEFAULT_MINOR,
71+
)),
72+
));
73+
ok!(write(
9174
"tests/fixtures/Roboto-Regular.otf",
92-
)
93-
.unwrap();
75+
ok!(super::decompress(&ok!(read(
76+
"tests/fixtures/Roboto-Regular.otf.woff"
77+
)))),
78+
));
9479
}
9580

9681
#[test]
9782
fn ttf() {
98-
super::convert(
99-
"tests/fixtures/Roboto-Regular.ttf",
100-
"tests/fixtures/Roboto-Regular.ttf.woff",
101-
)
102-
.unwrap();
103-
super::convert(
83+
ok!(write(
10484
"tests/fixtures/Roboto-Regular.ttf.woff",
85+
ok!(super::compress(
86+
&ok!(read("tests/fixtures/Roboto-Regular.ttf")),
87+
DEFAULT_MAJOR,
88+
DEFAULT_MINOR,
89+
)),
90+
));
91+
ok!(write(
10592
"tests/fixtures/Roboto-Regular.ttf",
106-
)
107-
.unwrap();
93+
ok!(super::decompress(&ok!(read(
94+
"tests/fixtures/Roboto-Regular.ttf.woff"
95+
)))),
96+
));
10897
}
10998
}

src/version2/mod.rs

Lines changed: 41 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
55
mod ffi;
66

7-
use std::io::{Error, Result};
8-
use std::path::Path;
9-
107
/// Compress.
11-
pub fn compress(data: &[u8], metadata: String, quality: usize, transform: bool) -> Option<Vec<u8>> {
12-
let metadata_length = metadata.len();
8+
pub fn compress<T>(data: &[u8], quality: usize, metadata: T, transform: bool) -> Option<Vec<u8>>
9+
where
10+
T: Into<Vec<u8>>,
11+
{
1312
let metadata = match std::ffi::CString::new(metadata) {
1413
Ok(metadata) => metadata,
1514
_ => return None,
1615
};
16+
let metadata_size = metadata.count_bytes();
1717
let size = unsafe {
1818
ffi::ComputeTTFToWOFF2Size(
1919
data.as_ptr() as *const _,
2020
data.len(),
2121
metadata.as_ptr() as *const _,
22-
metadata_length,
22+
metadata_size,
2323
)
2424
};
2525
let mut buffer = vec![0; size];
@@ -31,7 +31,7 @@ pub fn compress(data: &[u8], metadata: String, quality: usize, transform: bool)
3131
buffer.as_mut_ptr() as *mut _,
3232
&mut size as *mut _,
3333
metadata.as_ptr() as *const _,
34-
metadata_length,
34+
metadata_size,
3535
quality as core::ffi::c_int,
3636
transform as core::ffi::c_int,
3737
)
@@ -63,79 +63,51 @@ pub fn decompress(data: &[u8]) -> Option<Vec<u8>> {
6363
buffer.into()
6464
}
6565

66-
/// Compress or decompress.
67-
pub fn convert<T: AsRef<Path>>(
68-
source: T,
69-
destination: T,
70-
metadata: Option<String>,
71-
quality: Option<usize>,
72-
transform: Option<bool>,
73-
) -> Result<()> {
74-
let data = std::fs::read(source)?;
75-
let destination = destination.as_ref();
76-
let data = if destination
77-
.extension()
78-
.and_then(|value| value.to_str())
79-
.map(|value| value == "woff2")
80-
.unwrap_or(false)
81-
{
82-
match compress(
83-
&data,
84-
metadata.unwrap_or_default(),
85-
quality.unwrap_or(8),
86-
transform.unwrap_or(true),
87-
) {
88-
Some(data) => data,
89-
_ => return Err(Error::other("failed to compress")),
90-
}
91-
} else {
92-
match decompress(&data) {
93-
Some(data) => data,
94-
_ => return Err(Error::other("failed to decompress")),
95-
}
96-
};
97-
std::fs::write(destination, data)
98-
}
99-
10066
#[cfg(test)]
10167
mod tests {
68+
use std::fs::{read, write};
69+
70+
const DEFAULT_QUALITY: usize = 8;
71+
const DEFAULT_METADATA: &str = "";
72+
const DEFAULT_TRANSFORM: bool = true;
73+
74+
macro_rules! ok(($result:expr) => ($result.unwrap()));
75+
10276
#[test]
10377
fn otf() {
104-
super::convert(
105-
"tests/fixtures/Roboto-Regular.otf",
106-
"tests/fixtures/Roboto-Regular.otf.woff2",
107-
None,
108-
None,
109-
None,
110-
)
111-
.unwrap();
112-
super::convert(
78+
ok!(write(
11379
"tests/fixtures/Roboto-Regular.otf.woff2",
80+
ok!(super::compress(
81+
&ok!(read("tests/fixtures/Roboto-Regular.otf")),
82+
DEFAULT_QUALITY,
83+
DEFAULT_METADATA,
84+
DEFAULT_TRANSFORM,
85+
)),
86+
));
87+
ok!(write(
11488
"tests/fixtures/Roboto-Regular.otf",
115-
None,
116-
None,
117-
None,
118-
)
119-
.unwrap();
89+
ok!(super::decompress(&ok!(read(
90+
"tests/fixtures/Roboto-Regular.otf.woff2"
91+
)))),
92+
));
12093
}
12194

12295
#[test]
12396
fn ttf() {
124-
super::convert(
125-
"tests/fixtures/Roboto-Regular.ttf",
126-
"tests/fixtures/Roboto-Regular.ttf.woff2",
127-
None,
128-
None,
129-
None,
130-
)
131-
.unwrap();
132-
super::convert(
97+
ok!(write(
13398
"tests/fixtures/Roboto-Regular.ttf.woff2",
99+
ok!(super::compress(
100+
&ok!(read("tests/fixtures/Roboto-Regular.ttf")),
101+
DEFAULT_QUALITY,
102+
DEFAULT_METADATA,
103+
DEFAULT_TRANSFORM,
104+
)),
105+
));
106+
ok!(write(
134107
"tests/fixtures/Roboto-Regular.ttf",
135-
None,
136-
None,
137-
None,
138-
)
139-
.unwrap();
108+
ok!(super::decompress(&ok!(read(
109+
"tests/fixtures/Roboto-Regular.ttf.woff2"
110+
)))),
111+
));
140112
}
141113
}

0 commit comments

Comments
 (0)