-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #415 from mgeisler/binary-sizes
Add demo program to help compute binary sizes
- Loading branch information
Showing
6 changed files
with
189 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "textwrap-binary-sizes-demo" | ||
version = "0.1.0" | ||
authors = ["Martin Geisler <martin@geisler.net>"] | ||
description = "Textwrap binary size demo" | ||
repository = "https://github.com/mgeisler/textwrap" | ||
license-file = "../../LICENSE" | ||
edition = "2018" | ||
publish = false # This demo project should not be uploaded to crates.io | ||
|
||
[profile.release] | ||
lto = true | ||
codegen-units = 1 | ||
|
||
[features] | ||
smawk = ["textwrap/smawk"] | ||
unicode-linebreak = ["textwrap/unicode-linebreak"] | ||
unicode-width = ["textwrap/unicode-width"] | ||
hyphenation = ["textwrap/hyphenation"] | ||
|
||
[dependencies] | ||
textwrap = { path = "../../", default-features = false, optional = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
//! Compile Textwrap with differnet featurs and record the resulting | ||
//! binary size. Produces a Markdown table. | ||
|
||
use std::process::Command; | ||
use std::{fs, io}; | ||
|
||
fn compile(extra_args: &[&str]) -> io::Result<u64> { | ||
let status = Command::new("cargo") | ||
.arg("build") | ||
.arg("--quiet") | ||
.arg("--release") | ||
.args(extra_args) | ||
.status()?; | ||
if !status.success() { | ||
return Err(io::Error::new( | ||
io::ErrorKind::Other, | ||
format!("failed to compile: {}", status), | ||
)); | ||
} | ||
|
||
let path = "target/release/textwrap-binary-sizes-demo"; | ||
let status = Command::new("strip").arg(path).status()?; | ||
if !status.success() { | ||
return Err(io::Error::new( | ||
io::ErrorKind::Other, | ||
format!("failed to strip: {}", status), | ||
)); | ||
} | ||
|
||
let metadata = fs::metadata(path).map_err(|err| { | ||
io::Error::new( | ||
io::ErrorKind::Other, | ||
format!("failed to read metadata for {}: {}", path, err), | ||
) | ||
})?; | ||
Ok(metadata.len()) | ||
} | ||
|
||
struct PrettyError { | ||
error: io::Error, | ||
} | ||
|
||
// Simply print the inner error with `Display` (not `Debug`) to get a | ||
// human-readable error message. | ||
impl std::fmt::Debug for PrettyError { | ||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(fmt, "{}", self.error) | ||
} | ||
} | ||
|
||
impl From<io::Error> for PrettyError { | ||
fn from(error: io::Error) -> Self { | ||
Self { error } | ||
} | ||
} | ||
|
||
fn kb(size: u64) -> String { | ||
format!("{} KB", size / 1000) | ||
} | ||
|
||
fn main() -> Result<(), PrettyError> { | ||
macro_rules! printcols { | ||
($($value:expr),+) => { | ||
println!("| {:<a$} | {:>b$} | {:>c$} |", | ||
$($value),+, | ||
a = 40, b = 12, c = 8); | ||
}; | ||
} | ||
|
||
printcols!("Configuration", "Binary Size", "Delta"); | ||
printcols!(":---", "---:", "---:"); | ||
|
||
let features = [ | ||
("textwrap", "textwrap without default features"), | ||
("smawk", "textwrap with smawk"), | ||
("unicode-width", "textwrap with unicode-width"), | ||
("unicode-linebreak", "textwrap with unicode-linebreak"), | ||
]; | ||
let base_size = compile(&[])?; | ||
printcols!("quick-and-dirty implementation", kb(base_size), "— KB"); | ||
|
||
for (feature, label) in features.iter() { | ||
let size = compile(&["--features", feature])?; | ||
let delta = size - base_size; | ||
printcols!(label, kb(size), kb(delta)); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#[cfg(feature = "textwrap")] | ||
use textwrap::fill; | ||
|
||
#[cfg(not(feature = "textwrap"))] | ||
/// Quick-and-dirty fill implementation. | ||
/// | ||
/// Assumes single space between words, assumes 1 column per Unicode | ||
/// character (no emoji handling) and assumes that the longest word | ||
/// fit on the line (no handling of hyphens or over-long words). | ||
fn fill(text: &str, width: usize) -> String { | ||
let mut result = String::with_capacity(text.len()); | ||
let mut line_width = 0; | ||
for word in text.split_whitespace() { | ||
if line_width + 1 + word.len() > width { | ||
result.push('\n'); | ||
line_width = 0; | ||
} | ||
|
||
result.push_str(word); | ||
result.push(' '); | ||
line_width += word.len() + 1; | ||
} | ||
|
||
// Remove final ' '. | ||
result.truncate(result.len() - 1); | ||
result | ||
} | ||
|
||
fn main() { | ||
let text = "Hello, welcome to a world with beautifully wrapped \ | ||
text in your command-line programs. This includes \ | ||
non-ASCII text such as Açai, Jalapeño, Frappé"; | ||
for line in fill(text, 18).lines() { | ||
println!("│ {:18} │", line); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters