Repository: jugglerchris/rust-html2text (rust)

Issue:
Replace panicing APIs with such returning errors
This doesn't really affect me, since I only use the APIs that return errors, but it seems to me that it is a bad idea to provide deceptively simple looking functions that panic.
Panicing seems only reasonable if there's a way for the caller to check for simple preconditions that will cause a panic, but here whether `fn from_read` panics or not cannot reasonably be known at the callsite.

Pull request description:
replace panicing APIs with APIs that return errors
Closes #166 

Patch:
diff --git a/README.md b/README.md
index 9fc4e0f..cae2d3d 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ let html = b"
          <li>Item two</li>
          <li>Item three</li>
        </ul>";
-assert_eq!(from_read(&html[..], 20),
+assert_eq!(from_read(&html[..], 20).unwrap(),
            "\
 * Item one
 * Item two
diff --git a/examples/html2term.rs b/examples/html2term.rs
index 92e8a91..4804992 100644
--- a/examples/html2term.rs
+++ b/examples/html2term.rs
@@ -150,7 +150,8 @@ mod top {
         let (width, height) = (width as usize, height as usize);
 
         let mut file = std::fs::File::open(filename).expect("Tried to open file");
-        let annotated = html2text::from_read_rich(&mut file, width);
+        let annotated =
+            html2text::from_read_rich(&mut file, width).expect("Failed to convert from HTML");
 
         let link_map = find_links(&annotated);
         let frag_map = find_frags(&annotated);
diff --git a/src/lib.rs b/src/lib.rs
index 76b674e..2c752a8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,7 +14,7 @@
 //!          <li>Item two</li>
 //!          <li>Item three</li>
 //!        </ul>";
-//! assert_eq!(from_read(&html[..], 20),
+//! assert_eq!(from_read(&html[..], 20).unwrap(),
 //!            "\
 //! * Item one
 //! * Item two
@@ -2291,37 +2291,31 @@ pub fn parse(input: impl io::Read) -> Result<RenderTree> {
 
 /// Reads HTML from `input`, decorates it using `decorator`, and
 /// returns a `String` with text wrapped to `width` columns.
-pub fn from_read_with_decorator<R, D>(input: R, width: usize, decorator: D) -> String
+pub fn from_read_with_decorator<R, D>(input: R, width: usize, decorator: D) -> Result<String>
 where
     R: io::Read,
     D: TextDecorator,
 {
-    config::with_decorator(decorator)
-        .string_from_read(input, width)
-        .expect("Failed to convert to HTML")
+    config::with_decorator(decorator).string_from_read(input, width)
 }
 
 /// Reads HTML from `input`, and returns a `String` with text wrapped to
 /// `width` columns.
-pub fn from_read<R>(input: R, width: usize) -> String
+pub fn from_read<R>(input: R, width: usize) -> Result<String>
 where
     R: io::Read,
 {
-    config::plain()
-        .string_from_read(input, width)
-        .expect("Failed to convert to HTML")
+    config::plain().string_from_read(input, width)
 }
 
 /// Reads HTML from `input`, and returns text wrapped to `width` columns.
 /// The text is returned as a `Vec<TaggedLine<_>>`; the annotations are vectors
 /// of `RichAnnotation`.  The "outer" annotation comes first in the `Vec`.
-pub fn from_read_rich<R>(input: R, width: usize) -> Vec<TaggedLine<Vec<RichAnnotation>>>
+pub fn from_read_rich<R>(input: R, width: usize) -> Result<Vec<TaggedLine<Vec<RichAnnotation>>>>
 where
     R: io::Read,
 {
-    config::rich()
-        .lines_from_read(input, width)
-        .expect("Failed to convert to HTML")
+    config::rich().lines_from_read(input, width)
 }
 
 mod ansi_colours;


Test patch:
diff --git a/src/tests.rs b/src/tests.rs
index 44e2c6c..5d61ccd 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -16,7 +16,7 @@ macro_rules! assert_eq_str {
 }
 #[track_caller]
 fn test_html(input: &[u8], expected: &str, width: usize) {
-    let output = from_read(input, width);
+    let output = from_read(input, width).unwrap();
     assert_eq_str!(output, expected);
 }
 #[track_caller]
@@ -166,7 +166,7 @@ fn test_html_decorator<D>(input: &[u8], expected: &str, width: usize, decorator:
 where
     D: TextDecorator,
 {
-    let output = from_read_with_decorator(input, width, decorator);
+    let output = from_read_with_decorator(input, width, decorator).unwrap();
     assert_eq_str!(output, expected);
 }
 
@@ -354,34 +354,29 @@ fn test_colspan_large() {
 
 #[test]
 fn test_para() {
-    assert_eq_str!(from_read(&b"<p>Hello</p>"[..], 10), "Hello\n");
+    test_html(&b"<p>Hello</p>"[..], "Hello\n", 10);
 }
 
 #[test]
 fn test_para2() {
-    assert_eq_str!(
-        from_read(&b"<p>Hello, world!</p>"[..], 20),
-        "Hello, world!\n"
-    );
+    test_html(&b"<p>Hello, world!</p>"[..], "Hello, world!\n", 20);
 }
 
 #[test]
 fn test_blockquote() {
-    assert_eq_str!(
-        from_read(
-            &br#"<p>Hello</p>
+    test_html(
+        &br#"<p>Hello</p>
     <blockquote>One, two, three</blockquote>
     <p>foo</p>
 "#[..],
-            12
-        ),
         r#"Hello
 
 > One, two,
 > three
 
 foo
-"#
+"#,
+        12,
     );
 }
 
@@ -1791,7 +1786,7 @@ fn test_list_in_table() {
 fn test_max_width() {
     let html = r#"<table><td><p>3,266</p>"#;
     let decorator = crate::render::text_renderer::PlainDecorator::new();
-    let text = from_read_with_decorator(html.as_bytes(), usize::MAX, decorator.clone());
+    let text = from_read_with_decorator(html.as_bytes(), usize::MAX, decorator.clone()).unwrap();
     println!("{}", text);
 }
 
@@ -1804,7 +1799,7 @@ Test.
 End.
 </pre>"#;
     let decorator = crate::render::text_renderer::TrivialDecorator::new();
-    let text = from_read_with_decorator(html.as_bytes(), 20, decorator.clone());
+    let text = from_read_with_decorator(html.as_bytes(), 20, decorator.clone()).unwrap();
     assert_eq!(text, "Test.\n\n\nEnd.\n");
 }
 
@@ -1819,7 +1814,7 @@ fn test_links_outside_table() {
         </tbody>
         </table>
 "#;
-    let text = from_read(html.as_bytes(), 80);
+    let text = from_read(html.as_bytes(), 80).unwrap();
     assert_eq!(
         text,
         "──────────────┬───────────────
@@ -2008,7 +2003,7 @@ fn test_table_too_narrow() {
     </td>
 </tr></table>"
         .as_bytes();
-    from_read(tbl, 80);
+    from_read(tbl, 80).unwrap();
 }
 
 #[cfg(feature = "css")]