Skip to content

Commit

Permalink
Change Wrapper.splitter from T: WordSplitter to Box<dyn WordSplitter>
Browse files Browse the repository at this point in the history
Before, the Wrapper would be generic in the type of WordSplitter used.
This meant that Wrapper<NoHyphenation> would be a different type than
Wrapper<HyphenSplitter>.

The result is that you need to fix the type of WordSplitter at compile
time. This makes it hard to make interactive programs, something which
was raised in #178.

Making splitter a Box<dyn WordSplitter> makes the field less special.
We can therefore simplify the API by removing the with_splitter
constructor.

The performance is unchanged by this, even when testing with the
hyphenation feature enabled.
  • Loading branch information
mgeisler committed Sep 15, 2020
1 parent 089594d commit 62c643c
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 88 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ If you enable the `hyphenation` feature, you get support for automatic
hyphenation for [about 70 languages][patterns] via high-quality TeX
hyphenation patterns.

Your program must load the hyphenation pattern and call
`Wrapper::with_splitter` to use it:
Your program must load the hyphenation pattern and configure
`Wrapper::splitter` to use it:

```rust
use hyphenation::{Language, Load, Standard};
use textwrap::Wrapper;

fn main() {
let hyphenator = Standard::from_embedded(Language::EnglishUS).unwrap();
let wrapper = Wrapper::with_splitter(18, hyphenator);
let wrapper = Wrapper::new(18).splitter(Box::new(hyphenator));
let text = "textwrap: a small library for wrapping text.";
println!("{}", wrapper.fill(text))
}
Expand Down
7 changes: 4 additions & 3 deletions benches/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ pub fn benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("String lengths");
for length in [100, 200, 400, 800, 1600].iter() {
let text = lorem_ipsum(*length);
let mut wrapper = textwrap::Wrapper::new(LINE_LENGTH);
group.bench_with_input(BenchmarkId::new("fill", length), &text, |b, text| {
b.iter(|| textwrap::fill(text, LINE_LENGTH));
b.iter(|| wrapper.fill(text));
});
group.bench_with_input(BenchmarkId::new("wrap", length), &text, |b, text| {
b.iter(|| textwrap::wrap(text, LINE_LENGTH));
b.iter(|| wrapper.wrap(text));
});

#[cfg(feature = "hyphenation")]
Expand All @@ -37,7 +38,7 @@ pub fn benchmark(c: &mut Criterion) {
.join("benches")
.join("la.standard.bincode");
let dictionary = Standard::from_path(Language::Latin, &path).unwrap();
let wrapper = textwrap::Wrapper::with_splitter(LINE_LENGTH, dictionary);
wrapper.splitter = Box::new(dictionary);
group.bench_with_input(BenchmarkId::new("hyphenation", length), &text, |b, text| {
b.iter(|| wrapper.fill(text));
});
Expand Down
2 changes: 1 addition & 1 deletion examples/hyphenation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ fn main() {
fn main() {
let text = "textwrap: a small library for wrapping text.";
let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
let wrapper = textwrap::Wrapper::with_splitter(18, dictionary);
let wrapper = textwrap::Wrapper::new(18).splitter(Box::new(dictionary));
println!("{}", wrapper.fill(text));
}
24 changes: 10 additions & 14 deletions examples/layout.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
#[cfg(feature = "hyphenation")]
use hyphenation::{Language, Load};
use textwrap::Wrapper;

#[cfg(not(feature = "hyphenation"))]
fn new_wrapper<'a>() -> Wrapper<'a, textwrap::HyphenSplitter> {
Wrapper::new(0)
}

#[cfg(feature = "hyphenation")]
fn new_wrapper<'a>() -> Wrapper<'a, hyphenation::Standard> {
let dictionary = hyphenation::Standard::from_embedded(Language::EnglishUS).unwrap();
Wrapper::with_splitter(0, dictionary)
}

fn main() {
let example = "Memory safety without garbage collection. \
Concurrency without data races. \
Zero-cost abstractions.";
let mut prev_lines = vec![];
let mut wrapper = new_wrapper();

let mut wrapper = Wrapper::new(0);
#[cfg(feature = "hyphenation")]
{
use hyphenation::Load;
let language = hyphenation::Language::EnglishUS;
let dictionary = hyphenation::Standard::from_embedded(language).unwrap();
wrapper.splitter = Box::new(dictionary);
}

for width in 15..60 {
wrapper.width = width;
let lines = wrapper.wrap(example);
Expand Down
32 changes: 14 additions & 18 deletions examples/termwidth.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#[cfg(feature = "hyphenation")]
use hyphenation::{Language, Load, Standard};
#[cfg(feature = "terminal_size")]
use textwrap::Wrapper;

Expand All @@ -10,26 +8,24 @@ fn main() {

#[cfg(feature = "terminal_size")]
fn main() {
let example = "Memory safety without garbage collection. \
Concurrency without data races. \
Zero-cost abstractions.";

#[cfg(not(feature = "hyphenation"))]
fn new_wrapper<'a>() -> (&'static str, Wrapper<'a, textwrap::HyphenSplitter>) {
("without hyphenation", Wrapper::with_termwidth())
}
let (msg, wrapper) = ("without hyphenation", Wrapper::with_termwidth());

#[cfg(feature = "hyphenation")]
fn new_wrapper<'a>() -> (&'static str, Wrapper<'a, Standard>) {
let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
(
"with hyphenation",
Wrapper::with_splitter(textwrap::termwidth(), dictionary),
)
}
use hyphenation::Load;

#[cfg(feature = "hyphenation")]
let (msg, wrapper) = (
"with hyphenation",
Wrapper::with_termwidth().splitter(Box::new(
hyphenation::Standard::from_embedded(hyphenation::Language::EnglishUS).unwrap(),
)),
);

let example = "Memory safety without garbage collection. \
Concurrency without data races. \
Zero-cost abstractions.";
// Create a new Wrapper -- automatically set the width to the
// current terminal width.
let (msg, wrapper) = new_wrapper();
println!("Formatted {} in {} columns:", msg, wrapper.width);
println!("----");
println!("{}", wrapper.fill(example));
Expand Down
Loading

0 comments on commit 62c643c

Please sign in to comment.