Repository: mgeisler/textwrap (language: rust)

Issue:
Make term_size an optional dependency
Currently, `term_size` is a required dependency of this crate. This means that all consumers of this library **must** also install the transitive closure of `term_size`'s dependencies, even those who are not willing to use its functionality.

This is an especially important consideration given that `term_size` makes heavy use of `unsafe`, so crates with a zero-unsafe policy (such as one I am currently authoring) may not be able to use `textwrap` even though they don't actually need any of its `unsafe`-dependent functionality.

Since `with_termwidth()` is more or less trivial, and the `termwidth()` function literally just wraps `term_size` with a hardcoded default value, it seems to me that it is not the right trade-off that has been made in this regard.

Consequently, I suggest one of the following, in decreasing order of preference:
* Remove the `term_size` dependency, `termwidth()`, and `with_termwidth()` altogether, because the latter two are trivial and the default value of 80 might not be suitable for everyone anyway.
* Make `with_termwidth()` and `termwidth()` a non-default, optional feature and `term_size` an optional dependency, so they are not included by default, but those who are willing to use the functionality can still continue doing so without breaking code changes.
* Make `with_termwidth()` and `termwidth()` a default, optional feature and `term_size` an optional dependency, so they are included by default, but those who are not willing to use the functionality can opt out.

This is blocking https://github.com/kbknapp/clap-rs/issues/1055.



Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index b529f511..bb0966c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@ appveyor = { repository = "mgeisler/textwrap" }
 
 [dependencies]
 unicode-width = "0.1.3"
-term_size = "0.3.0"
+term_size = { version = "0.3.0", optional = true }
 hyphenation = { version = "0.6.1", optional = true }
 
 [dev-dependencies]
diff --git a/README.md b/README.md
index 100db88b..376d0822 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,14 @@ dependency as:
 textwrap = { version = "0.8", features = ["hyphenation"] }
 ```
 
+To conveniently wrap text at the current terminal width, enable the
+`term_size` feature:
+
+```toml
+[dependencies]
+textwrap = { version = "0.8", features = ["term_size"] }
+```
+
 ## Documentation
 
 **[API documentation][api-docs]**
@@ -175,10 +183,18 @@ This section lists the largest changes per release.
 
 ### Unreleased
 
-All public structs now implement `Debug`.
+The dependency on `term_size` is now optional, and by default this
+feature is not enabled. This is a *breaking change* for users of
+`Wrapper::with_termwidth`. Enable the `term_size` feature to restore
+the old functionality.
 
 Added a regression test for case where width is set to usize::MAX.
-Thanks @Fraser999!
+Thanks @Fraser999! All public structs now implement `Debug`.
+
+Issues closed:
+
+* Fixed [#101][issue-101]: Remove `term_size` as a (hard required)
+  dependency.
 
 ### Version 0.8.0 — September 4th, 2017
 
@@ -303,4 +319,5 @@ Contributions will be accepted under the same license.
 [issue-59]: ../../issues/59
 [issue-61]: ../../issues/61
 [issue-81]: ../../issues/81
+[issue-101]: ../../issues/101
 [mit]: LICENSE
diff --git a/examples/termwidth.rs b/examples/termwidth.rs
index e8ab3ad7..7d81a5c6 100644
--- a/examples/termwidth.rs
+++ b/examples/termwidth.rs
@@ -1,14 +1,19 @@
+#[cfg(feature = "term_size")]
 extern crate textwrap;
 
-use textwrap::Wrapper;
+#[cfg(not(feature = "term_size"))]
+fn main() {
+    println!("Please enable the term_size feature to run this example.");
+}
 
+#[cfg(feature = "term_size")]
 fn main() {
     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 wrapper = Wrapper::with_termwidth();
+    let wrapper = textwrap::Wrapper::with_termwidth();
     println!("Formatted in within {} columns:", wrapper.width);
     println!("----");
     println!("{}", wrapper.fill(example));
diff --git a/src/lib.rs b/src/lib.rs
index 44708fac..fc129d73 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -46,6 +46,7 @@
 #![deny(missing_debug_implementations)]
 
 extern crate unicode_width;
+#[cfg(feature = "term_size")]
 extern crate term_size;
 #[cfg(feature = "hyphenation")]
 extern crate hyphenation;
@@ -266,6 +267,7 @@ impl<'a> Wrapper<'a, HyphenSplitter> {
     ///
     /// let wrapper = Wrapper::new(termwidth());
     /// ```
+    #[cfg(feature = "term_size")]
     pub fn with_termwidth() -> Wrapper<'a, HyphenSplitter> {
         Wrapper::new(termwidth())
     }
@@ -715,6 +717,7 @@ impl<'a> WrapIterImpl<'a> {
 ///     .initial_indent("  ")
 ///     .subsequent_indent("  ");
 /// ```
+#[cfg(feature = "term_size")]
 pub fn termwidth() -> usize {
     term_size::dimensions_stdout().map_or(80, |(w, _)| w)
 }


Test patch: