Repository: rustache/rustache (language: rust)

Issue:
migrate from MemStream to std::io::Cursor
The MemStream crate implements an in-memory type that supports `Read`, `Write`, and `Seek`. The in-memory type is serviced by a `Vec<u8>`. It should be possible at this point to use `std::io::Cursor<Vec<u8>>` to replace it.



Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index fc9f55b..1e60dfa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,4 +18,3 @@ path = "src/lib.rs"
 [dependencies]
 regex = "^0.1"
 rustc-serialize = "^0.3"
-memstream = "0.0.1"
diff --git a/src/rustache.rs b/src/rustache.rs
index dfacbf8..f0d0704 100644
--- a/src/rustache.rs
+++ b/src/rustache.rs
@@ -1,11 +1,8 @@
-extern crate memstream;
-
 use std::fs::File;
-use std::io::Read;
+use std::io::{Cursor, Read};
 use std::path::Path;
 use compiler;
 use parser;
-use self::memstream::MemStream;
 use rustc_serialize::json::Json;
 use rustc_serialize::json::Json::{Boolean, Null, I64, U64, F64, Array, Object};
 use rustc_serialize::json::Json::String as JString;
@@ -22,10 +19,10 @@ pub trait Render<R: Read> {
 }
 
 /// Implement the `renderable` trait on the HashBuilder type
-impl<'a> Render<MemStream> for HashBuilder<'a> {
-    fn render(&self, template: &str) -> RustacheResult<MemStream> {
+impl<'a> Render<Cursor<Vec<u8>>> for HashBuilder<'a> {
+    fn render(&self, template: &str) -> RustacheResult<Cursor<Vec<u8>>> {
         // Create the stream we are going to write to.
-        let mut stream = MemStream::new();
+        let mut stream = Cursor::new(Vec::new());
 
         // Create our nodes
         let tokens = compiler::create_tokens(template);
@@ -41,14 +38,14 @@ impl<'a> Render<MemStream> for HashBuilder<'a> {
 
 
 /// Implement the `renderable` trait on the JSON type
-impl Render<MemStream> for Json {
-    fn render(&self, template: &str) -> RustacheResult<MemStream> {
+impl Render<Cursor<Vec<u8>>> for Json {
+    fn render(&self, template: &str) -> RustacheResult<Cursor<Vec<u8>>> {
        parse_json(self).render(template)
     }
 }
 
-impl Render<MemStream> for Path {
-    fn render(&self, template: &str) -> RustacheResult<MemStream> {
+impl Render<Cursor<Vec<u8>>> for Path {
+    fn render(&self, template: &str) -> RustacheResult<Cursor<Vec<u8>>> {
 
         return match read_file(self) {
             Ok(text) => {
@@ -68,8 +65,8 @@ impl Render<MemStream> for Path {
     }
 }
 
-impl Render<MemStream> for String {
-    fn render(&self, template: &str) -> RustacheResult<MemStream> {
+impl Render<Cursor<Vec<u8>>> for String {
+    fn render(&self, template: &str) -> RustacheResult<Cursor<Vec<u8>>> {
 
         let json = match Json::from_str(&self[..]) {
             Ok(json) => json,
diff --git a/src/template.rs b/src/template.rs
index ee7b69d..633cbca 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -2,7 +2,7 @@ use std::path::Path;
 use std::fs;
 use std::fs::File;
 use std::fmt;
-use std::io::{Read,Write};
+use std::io::{Read, Write};
 
 use compiler;
 use parser;
@@ -619,15 +619,11 @@ impl Template {
 
 #[cfg(test)]
 mod template_tests {
-    extern crate memstream;
-
     use std::fs::File;
     use std::path::Path;
-    use std::io::Write;
+    use std::io::{self, Cursor, Seek, SeekFrom};
     use std::str;
 
-    use self::memstream::MemStream;
-
     use parser;
     use parser::Node;
     use parser::Node::{Value, Static, Unescaped, Section, Part};
@@ -704,26 +700,26 @@ mod template_tests {
         let s2 = "1<2 <b>hello</b>";
         let a2 = "1&lt;2 &lt;b&gt;hello&lt;/b&gt;";
 
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Value("value", "{{ value }}".to_string())];
         let data = HashBuilder::new().insert_string("value", s1);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!(a1, str::from_utf8(w.as_slice()).unwrap());
+        assert_eq!(a1, str::from_utf8(w.get_ref()).unwrap());
 
-        w = MemStream::new();
+        w = Cursor::new(Vec::new());
         let newdata = HashBuilder::new().insert_string("value", s2);
         let rv = Template::new().render_data(&mut w, &newdata, &nodes);
         match rv { _ => {} }
 
-        assert_eq!(a2, str::from_utf8(w.as_slice()).unwrap());
+        assert_eq!(a2, str::from_utf8(w.get_ref()).unwrap());
     }
 
     #[test]
     fn test_section_tag_iteration() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let template = "{{#repo}}<b>{{name}}</b>{{/repo}}";
         let tokens = compiler::create_tokens(template);
         let nodes = parser::parse_nodes(&tokens);
@@ -736,61 +732,61 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<b>resque</b><b>hub</b><b>rip</b>".to_string(), String::from_utf8(w.unwrap()).unwrap())
+        assert_eq!("<b>resque</b><b>hub</b><b>rip</b>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_not_escape_html() {
         let s = "1<2 <b>hello</b>";
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Unescaped("value", "{{ value }}".to_string())];
         let data = HashBuilder::new().insert_string("value", s);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!(s, str::from_utf8(w.as_slice()).unwrap());
+        assert_eq!(s, String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_render_to_io_stream() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let data = HashBuilder::new().insert_string("value1", "The heading");
         let nodes: Vec<Node> = vec![Static("<h1>"), Value("value1", "{{ value1 }}".to_string()), Static("</h1>")];
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<h1>The heading</h1>".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("<h1>The heading</h1>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_unescaped_node_correct_bool_false_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("<h1>"), Unescaped("value1", "{{& value1 }}".to_string()), Static("</h1>")];
         let data = HashBuilder::new().insert_bool("value1", false);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<h1>false</h1>".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("<h1>false</h1>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_unescaped_node_correct_bool_true_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("<h1>"), Unescaped("value1", "{{& value1 }}".to_string()), Static("</h1>")];
         let data = HashBuilder::new().insert_bool("value1", true);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<h1>true</h1>".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("<h1>true</h1>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_section_value_string_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Section("value1", vec![Value("value", "{{ value }}".to_string())], false, "{{# value1 }}".to_string(), "{{/ value1 }}".to_string())];
         let data = HashBuilder::new()
             .insert_hash("value1", |builder| {
@@ -800,12 +796,12 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("&lt;Section Value&gt;".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("&lt;Section Value&gt;".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_section_multiple_value_string_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Section("names", vec![Value("name", "{{ name }}".to_string())], false, "{{# names }}".to_string(), "{{/ names }}".to_string())];
         let data = HashBuilder::new()
             .insert_hash("names", |builder| {
@@ -820,12 +816,12 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("tomrobertjoe".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("tomrobertjoe".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     // #[test]
     // fn test_excessively_nested_data() {
-    //     let mut w = MemStream::new();
+    //     let mut w = Cursor::new(Vec::new());
     //     let nodes: Vec<Node> = vec![Section("hr", vec![Section("people", vec![Value("name", "{{ name }}".to_string())], false, "{{# people }}".to_string(), "{{/ people }}".to_string())], false, "{{# hr }}".to_string(), "{{/ hr }}".to_string())];
     //     let data = HashBuilder::new()
     //         .insert_hash("hr", |builder| {
@@ -841,12 +837,12 @@ mod template_tests {
     //         });
 
     //     let rv = Template::new().render_data(&mut w, &data, &nodes);
-    //     assert_eq!("tomrobertjoe".to_string(), String::from_utf8(w.unwrap()).unwrap());
+    //     assert_eq!("tomrobertjoe".to_string(), String::from_utf8(w.into_inner()).unwrap());
     // }
 
     #[test]
     fn test_unescaped_node_lambda_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("<h1>"), Unescaped("func1", "{{& func1 }}".to_string()), Static("</h1>")];
         let mut f = |_| { "heading".to_string() };
         let data = HashBuilder::new().insert_lambda("func1", &mut f);
@@ -854,12 +850,12 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<h1>heading</h1>".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("<h1>heading</h1>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_value_node_lambda_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("<h1>"), Value("func1", "{{ func1 }}".to_string()), Static("</h1>")];
         let mut f = |_| { "heading".to_string() };
         let data = HashBuilder::new().insert_lambda("func1", &mut f);
@@ -867,19 +863,18 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("<h1>heading</h1>".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("<h1>heading</h1>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     // #[test]
     // fn test_spec_lambdas_interpolation_using_render_text() {
-    //     let mut s = MemStream::new();
+    //     let mut s = Cursor::new(Vec::new());
     //     let data = HashBuilder::new()
     //                 .insert_lambda("lambda", |_| {
     //                      "world".to_string()
     //                  });
     //     let s = rustache::render_text("Hello, {{lambda}}!", data);
-
-    //     assert_eq!("Hello, world!".to_string(), String::from_utf8(s.unwrap()).unwrap());
+    //     assert_eq!("Hello, world!".to_string(), String::from_utf8(w.into_inner()).unwrap());
     // }
 
     // #[test]
@@ -892,36 +887,36 @@ mod template_tests {
 
     //     let s = rustache::render_text("<{{^lambda}}{{static}}{{/lambda}}>", data);
 
-    //     assert_eq!("<>".to_string(), String::from_utf8(s.unwrap()).unwrap());
+    //     assert_eq!("<>".to_string(), String::from_utf8(w.into_inner()).unwrap());
     // }
 
     #[test]
     fn test_value_node_correct_false_bool_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Value("value1", "{{ value1 }}".to_string())];
         let data = HashBuilder::new().insert_bool("value1", false);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("false".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("false".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_value_node_correct_true_bool_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Value("value1", "{{ value1 }}".to_string())];
         let data = HashBuilder::new().insert_bool("value1", true);
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!("true".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("true".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_partial_node_correct_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("A wise woman once said: "), Part("hopper_quote.partial", "{{> hopper_quote.partial }}")];
         let data = HashBuilder::new().insert_string("author", "Grace Hopper")
                                      .set_partials_path("test_data");
@@ -932,12 +927,12 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!(s, String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!(s, String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_partial_node_correct_data_with_extra() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let nodes: Vec<Node> = vec![Static("A wise woman once said: "), Part("hopper_quote.partial", "{{> hopper_quote.partial }}"), Static(" something else "), Value("extra", "{{ extra }}".to_string())];
         let data = HashBuilder::new().insert_string("author", "Grace Hopper")
                                      .insert_string("extra", "extra data")
@@ -949,12 +944,12 @@ mod template_tests {
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
 
-        assert_eq!(s, String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!(s, String::from_utf8(w.into_inner()).unwrap());
     }
 
     #[test]
     fn test_section_node_partial_node_correct_data() {
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let data = HashBuilder::new()
             .set_partials_path("test_data")
             .insert_hash("people", |builder| {
@@ -979,7 +974,8 @@ mod template_tests {
         match rv { _ => {} }
 
         let mut f = File::create(&Path::new("test_data/section_with_partial.html")).unwrap();
-        let completed = f.write(&w.unwrap()[..]);
+        w.seek(SeekFrom::Start(0)).unwrap();
+        let completed = io::copy(&mut w, &mut f);
         assert_eq!(completed.is_ok(), true);
     }
 
@@ -998,7 +994,7 @@ mod template_tests {
     #[test]
     fn test_spec_lambda_not_cached_on_interpolation() {
         let mut planets = vec!["Jupiter", "Earth", "Saturn"];
-        let mut w = MemStream::new();
+        let mut w = Cursor::new(Vec::new());
         let mut tokens = compiler::create_tokens("{{lambda}} == {{&lambda}} == {{lambda}}");
         let nodes = parser::parse_nodes(&mut tokens);
         let mut f = |_| { planets.pop().unwrap().to_string() };
@@ -1007,7 +1003,7 @@ mod template_tests {
 
         let rv = Template::new().render_data(&mut w, &data, &nodes);
         match rv { _ => {} }
-        assert_eq!("Saturn == Earth == Jupiter".to_string(), String::from_utf8(w.unwrap()).unwrap());
+        assert_eq!("Saturn == Earth == Jupiter".to_string(), String::from_utf8(w.into_inner()).unwrap());
     }
 
 }


Test patch:
diff --git a/tests/test_spec_comments.rs b/tests/test_spec_comments.rs
index 76d4e44..0fdc008 100644
--- a/tests/test_spec_comments.rs
+++ b/tests/test_spec_comments.rs
@@ -12,7 +12,7 @@ fn test_spec_inline_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("12345{{! Comment Block! }}67890", data);
 
-    assert_eq!("1234567890".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1234567890".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Multiline
@@ -30,7 +30,7 @@ fn test_spec_multiline_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("12345{{!\nThis is a\nmulti-line comment...\n}}67890", data);
 
-    assert_eq!("1234567890".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1234567890".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Standalone
@@ -48,7 +48,7 @@ fn test_spec_standalone_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("Begin.\n{{! Comment Block! }}\nEnd.", data);
 
-    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Indented Standalone
@@ -66,7 +66,7 @@ fn test_spec_indented_standalone_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("Begin.\n\t{{! Indented Comment Block! }}\nEnd.", data);
 
-    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Standalone Line Endings
@@ -79,7 +79,7 @@ fn test_spec_standalone_line_ending_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("|\r\n{{! Standalone Comment }}\r\n|", data);
 
-    assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Standalone Without Previous Line
@@ -92,7 +92,7 @@ fn test_spec_standalone_line_ending_comment() {
 //     let data = HashBuilder::new();
 //     let rv = rustache::render_text("  {{! I'm Still Standalone }}\n!", data);
 
-//     assert_eq!("!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Standalone Without Newline
@@ -105,7 +105,7 @@ fn test_spec_standalone_line_ending_comment() {
 //     let data = HashBuilder::new();
 //     let rv = rustache::render_text("!\n  {{! I'm Still Standalone }}", data);
 
-//     assert_eq!("!\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("!\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Multiline Standalone
@@ -125,7 +125,7 @@ fn test_spec_multiline_standalone_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("Begin.\n{{!\nSomething's going on here...\n}}\nEnd.", data);
 
-    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Indented Multiline Standalone
@@ -145,7 +145,7 @@ fn test_spec_indented_multiline_standalone_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("Begin.\n{{!\n\tSomething's going on here...\n}}\nEnd.", data);
 
-    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Begin.\nEnd.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Indented Inline
@@ -158,7 +158,7 @@ fn test_spec_indented_inline_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("  12 {{! 34 }}\n", data);
 
-    assert_eq!("  12 \n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  12 \n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Surrounding Whitespace
@@ -171,5 +171,5 @@ fn test_spec_surrounding_whitespace_comment() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("12345 {{! Comment Block! }} 67890", data);
 
-    assert_eq!("12345  67890".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
-}
\ No newline at end of file
+    assert_eq!("12345  67890".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
+}
diff --git a/tests/test_spec_interpolation.rs b/tests/test_spec_interpolation.rs
index b5285c1..d99d592 100644
--- a/tests/test_spec_interpolation.rs
+++ b/tests/test_spec_interpolation.rs
@@ -15,7 +15,7 @@ fn test_spec_interpolation_none() {
 
     let rv = rustache::render_text("Hello from {Mustache}!", data);
 
-    assert_eq!("Hello from {Mustache}!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Hello from {Mustache}!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Basic Interpolation
@@ -31,7 +31,7 @@ fn test_spec_interpolation_basic() {
 
     let rv = rustache::render_text("Hello, {{subject}}!", data);
 
-    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: HTML Escaping
@@ -47,7 +47,7 @@ fn test_spec_interpolation_html_escaping() {
 
     let rv = rustache::render_text("These characters should be HTML escaped: {{forbidden}}", data);
 
-    assert_eq!("These characters should be HTML escaped: &amp; &quot; &lt; &gt;".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("These characters should be HTML escaped: &amp; &quot; &lt; &gt;".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache
@@ -63,7 +63,7 @@ fn test_spec_interpolation_no_html_escaping_triple_mustache() {
 
     let rv = rustache::render_text("These characters should not be HTML escaped: {{{forbidden}}}", data);
 
-    assert_eq!("These characters should not be HTML escaped: & \" < >".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("These characters should not be HTML escaped: & \" < >".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand
@@ -79,7 +79,7 @@ fn test_spec_interpolation_no_html_escaping_ampersand() {
 
     let rv = rustache::render_text("These characters should not be HTML escaped: {{&forbidden}}", data);
 
-    assert_eq!("These characters should not be HTML escaped: & \" < >".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("These characters should not be HTML escaped: & \" < >".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Basic Integer Interpolation
@@ -93,7 +93,7 @@ fn test_spec_interpolation_integer_basic() {
 
     let rv = rustache::render_text("{{mph}} miles an hour!", data);
 
-    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache Integer Interpolation
@@ -107,7 +107,7 @@ fn test_spec_interpolation_integer_triple_mustache() {
 
     let rv = rustache::render_text("{{{mph}}} miles an hour!", data);
 
-    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand Integer Interpolation
@@ -121,7 +121,7 @@ fn test_spec_interpolation_integer_ampersand() {
 
     let rv = rustache::render_text("{{mph}} miles an hour!", data);
 
-    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("85 miles an hour!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Basic Decimal Interpolation
@@ -135,7 +135,7 @@ fn test_spec_interpolation_float_basic() {
 
     let rv = rustache::render_text("{{power}} jiggawatts!", data);
 
-    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache Decimal Interpolation
@@ -149,7 +149,7 @@ fn test_spec_interpolation_float_triple_mustache() {
 
     let rv = rustache::render_text("{{{power}}} jiggawatts!", data);
 
-    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand Decimal Interpolation
@@ -163,7 +163,7 @@ fn test_spec_interpolation_float_ampersand() {
 
     let rv = rustache::render_text("{{&power}} jiggawatts!", data);
 
-    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1.21 jiggawatts!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Basic Context Miss Interpolation
@@ -177,7 +177,7 @@ fn test_spec_interpolation_context_miss() {
 
     let rv = rustache::render_text("I ({{cannot}}) be seen!", data);
 
-    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache Context Miss Interpolation
@@ -191,7 +191,7 @@ fn test_spec_interpolation_context_miss_triple_mustache() {
 
     let rv = rustache::render_text("I ({{{cannot}}}) be seen!", data);
 
-    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand Context Miss Interpolation
@@ -205,7 +205,7 @@ fn test_spec_interpolation_context_miss_ampersand() {
 
     let rv = rustache::render_text("I ({{cannot}}) be seen!", data);
 
-    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("I () be seen!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Basic Interpolation
@@ -219,7 +219,7 @@ fn test_spec_interpolation_dotted_names_basic() {
 
     let rv = rustache::render_text("\"{{person.name}}\" == \"{{#person}}{{name}}{{/person}}\"", data);
 
-    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Triple Mustache Interpolation
@@ -236,7 +236,7 @@ fn test_spec_interpolation_dotted_names_triple_mustache() {
 
     let rv = rustache::render_text("\"{{{person.name}}}\" == \"{{#person}}{{{name}}}{{/person}}\"", data);
 
-    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Ampersand Interpolation
@@ -253,7 +253,7 @@ fn test_spec_interpolation_dotted_names_ampersand() {
 
     let rv = rustache::render_text("\"{{&person.name}}\" == \"{{#person}}{{&name}}{{/person}}\"", data);
 
-    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"Joe\" == \"Joe\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Arbitrary Depth
@@ -279,7 +279,7 @@ fn test_spec_interpolation_dotted_names_arbitrary_depth() {
 
     let rv = rustache::render_text("\"{{a.b.c.d.e.name}}\" == \"Phil\"", data);
 
-    assert_eq!("\"Phil\" == \"Phil\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"Phil\" == \"Phil\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Broken Chains
@@ -294,7 +294,7 @@ fn test_spec_interpolation_dotted_broken_chains() {
 
     let rv = rustache::render_text("\"{{a.b.c}}\" == \"\"", data);
 
-    assert_eq!("\"\" == \"\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"\" == \"\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Broken Chain Resolution
@@ -318,7 +318,7 @@ fn test_spec_interpolation_dotted_broken_chain_resolution() {
 
     let rv = rustache::render_text("\"{{a.b.c}}\" == \"\"", data);
 
-    assert_eq!("\"\" == \"\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"\" == \"\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Initial Resolution
@@ -354,7 +354,7 @@ fn test_spec_interpolation_dotted_initial_resolution() {
 
     let rv = rustache::render_text("\"{{#a}}{{b.c.d.e.name}}{{/a}}\" == \"Phil\"", data);
 
-    assert_eq!("\"Phil\" == \"Phil\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"Phil\" == \"Phil\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Context Precedence
@@ -380,7 +380,7 @@ fn test_spec_interpolation_dotted_context_precedence() {
 
     let rv = rustache::render_text("{{#a}}{{b.c}}{{/a}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Interpolation - Surrounding Whitespace
@@ -394,7 +394,7 @@ fn test_spec_interpolation_surrounding_whitespace_basic() {
 
     let rv = rustache::render_text("| {{string}} |", data);
 
-    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache - Surrounding Whitespace
@@ -408,7 +408,7 @@ fn test_spec_interpolation_surrounding_whitespace_triple_mustache() {
 
     let rv = rustache::render_text("| {{{string}}} |", data);
 
-    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand - Surrounding Whitespace
@@ -422,7 +422,7 @@ fn test_spec_interpolation_surrounding_whitespace_ampersand() {
 
     let rv = rustache::render_text("| {{&string}} |", data);
 
-    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| --- |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Interpolation - Standalone
@@ -436,7 +436,7 @@ fn test_spec_interpolation_standalone_basic() {
 
     let rv = rustache::render_text("  {{string}}\n", data);
 
-    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache - Standalone
@@ -450,7 +450,7 @@ fn test_spec_interpolation_standalone_triple_mustache() {
 
     let rv = rustache::render_text("  {{{string}}}\n", data);
 
-    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand - Standalone
@@ -464,7 +464,7 @@ fn test_spec_interpolation_standalone_ampersand() {
 
     let rv = rustache::render_text("  {{&string}}\n", data);
 
-    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  ---\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Interpolation With Padding
@@ -478,7 +478,7 @@ fn test_spec_interpolation_with_padding() {
 
   let rv = rustache::render_text("|{{ string }}|", data);
 
-  assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+  assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Triple Mustache With Padding
@@ -492,7 +492,7 @@ fn test_spec_interpolation_triple_mustache_with_padding() {
 
     let rv = rustache::render_text("|{{{ string }}}|", data);
 
-    assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Ampersand With Padding
@@ -506,6 +506,6 @@ fn test_spec_interpolation_ampersand_with_padding() {
 
     let rv = rustache::render_text("|{{& string }}|", data);
     
-    assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|---|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
diff --git a/tests/test_spec_inverted.rs b/tests/test_spec_inverted.rs
index 72961a3..53d07db 100644
--- a/tests/test_spec_inverted.rs
+++ b/tests/test_spec_inverted.rs
@@ -12,7 +12,7 @@ fn test_spec_inverted_falsy_bool() {
     let data = HashBuilder::new().insert_bool("boolean", false);
     let rv = rustache::render_text("{{^boolean}}This should be rendered.{{/boolean}}", data);
 
-    assert_eq!("This should be rendered.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("This should be rendered.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Truthy
@@ -25,7 +25,7 @@ fn test_spec_inverted_truthy_bool() {
     let data = HashBuilder::new().insert_bool("boolean", true);
     let rv = rustache::render_text("{{^boolean}}This should not be rendered.{{/boolean}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Context
@@ -38,7 +38,7 @@ fn test_spec_inverted_truthy_hash() {
     let data = HashBuilder::new().insert_hash("context", |builder| { builder.insert_string("name", "joe") });
     let rv = rustache::render_text("{{^context}}Hi {{name}}.{{/context}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: List
@@ -57,7 +57,7 @@ fn test_spec_inverted_truthy_vec() {
     });
     let rv = rustache::render_text("{{^list}}{{n}}{{/list}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Empty List
@@ -72,7 +72,7 @@ fn test_spec_inverted_falsy_on_empty_vec() {
     });
     let rv = rustache::render_text("{{^list}}Yay lists!{{/list}}", data);
 
-    assert_eq!("Yay lists!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Yay lists!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Doubled
@@ -95,7 +95,7 @@ fn test_spec_inverted_falsy_on_empty_vec() {
 //     let data = HashBuilder::new().insert_bool("bool", false).insert_string("two", "second");
 //     let rv = rustache::render_text("{{^bool}}\n* first\n{{/bool}}\n* {{two}}\n{{^bool}}\n* third\n{{/bool}}", data);
 
-//     assert_eq!("* first\n* second\n* third".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("* first\n* second\n* third".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Nested (Falsey)
@@ -109,7 +109,7 @@ fn test_spec_inverted_nested_falsy() {
     let data = HashBuilder::new().insert_bool("bool", false);
     let rv = rustache::render_text("| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", data);
 
-    assert_eq!("| A B C D E |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| A B C D E |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Nested (Truthy)
@@ -122,7 +122,7 @@ fn test_spec_inverted_nested_truthy() {
     let data = HashBuilder::new().insert_bool("bool", true);
     let rv = rustache::render_text("| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |", data);
 
-    assert_eq!("| A  E |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| A  E |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Context Misses
@@ -135,7 +135,7 @@ fn test_spec_inverted_missing_falsey() {
     let data = HashBuilder::new();
     let rv = rustache::render_text("[{{^missing}}Cannot find key 'missing'!{{/missing}}]", data);
 
-    assert_eq!("[Cannot find key 'missing'!]".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("[Cannot find key 'missing'!]".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Truthy
@@ -155,7 +155,7 @@ fn test_spec_inverted_missing_falsey() {
 //         });
 //  let rv = rustache::render_text("'{{^a.b.c}}Not Here{{/a.b.c}}' == ''", data)
 
-//     assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Dotted Names - Falsey
@@ -175,7 +175,7 @@ fn test_spec_falsey_dotted_names_valid_inverted_section_tags() {
         });
     let rv = rustache::render_text("'{{^a.b.c}}Not Here{{/a.b.c}}' == 'Not Here'", data);
 
-    assert_eq!("'Not Here' == 'Not Here'".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("'Not Here' == 'Not Here'".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Dotted Names - Broken Chains
@@ -194,7 +194,7 @@ fn test_spec_inverted_surrounding_whitespace() {
     let data = HashBuilder::new().insert_bool("boolean", false);
     let rv = rustache::render_text(" | {{^boolean}}\t|\t{{/boolean}} | \n", data);
 
-    assert_eq!(" | \t|\t | \n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!(" | \t|\t | \n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Internal Whitespace
@@ -208,7 +208,7 @@ fn test_spec_inverted_surrounding_whitespace() {
 
 //     let rv = rustache::render_text(" | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", data);
 
-//     assert_eq!(" |  \n  | \n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!(" |  \n  | \n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Indented Inline Sections
@@ -221,7 +221,7 @@ fn test_spec_inverted_indented_inline_sections() {
     let data = HashBuilder::new().insert_bool("boolean", false);
     let rv = rustache::render_text(" {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n", data);
 
-    assert_eq!(" NO\n WAY\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!(" NO\n WAY\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Standalone Lines
@@ -243,7 +243,7 @@ fn test_spec_inverted_indented_inline_sections() {
 
 //     let rv = rustache::render_text("| This Is\n{{^boolean}}\n|\n{{/boolean}}\n| A Line", data)
 
-//     assert_eq!("| This Is\n|\n| A Line".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("| This Is\n|\n| A Line".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Standalone Indented Lines
@@ -265,7 +265,7 @@ fn test_spec_inverted_indented_inline_sections() {
 
 //     let rv = rustache::render_text("| This Is\n  {{^boolean}}\n|\n  {{/boolean}}\n| A Line", data)
 
-//     assert_eq!("| This Is\n|\n| A Line".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("| This Is\n|\n| A Line".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Standalone Line Endings
@@ -279,7 +279,7 @@ fn test_spec_inverted_indented_inline_sections() {
 
 //     let rv = rustache::render_text("|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|", data)
 
-//     assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Standalone Without Previous Line
@@ -293,7 +293,7 @@ fn test_spec_inverted_indented_inline_sections() {
 
 //     let rv = rustache::render_text("  {{^boolean}}\n^{{/boolean}}\n/", data);
 
-//     assert_eq!("^\n/".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("^\n/".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Standalone Without Newline
@@ -307,7 +307,7 @@ fn test_spec_inverted_indented_inline_sections() {
 
 //     let rv = rustache::render_text("^{{^boolean}}\n/\n  {{/boolean}}", data);
 
-//     assert_eq!("^\n/\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("^\n/\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 // - name: Padding
@@ -320,7 +320,7 @@ fn test_spec_inverted_whitespace_insensitivity() {
     let data = HashBuilder::new().insert_bool("boolean", false);
     let rv = rustache::render_text("|{{^ boolean }}={{/ boolean }}|", data);
 
-    assert_eq!("|=|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|=|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 
diff --git a/tests/test_spec_lambdas.rs b/tests/test_spec_lambdas.rs
index e681549..1eecb81 100644
--- a/tests/test_spec_lambdas.rs
+++ b/tests/test_spec_lambdas.rs
@@ -22,7 +22,7 @@ fn test_spec_lambdas_interpolation() {
 
     let rv = rustache::render_text("Hello, {{lambda}}!", data);
 
-    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Interpolation - Expansion
@@ -47,7 +47,7 @@ fn test_spec_lambdas_interpolation_expansion() {
 
     let rv = rustache::render_text("Hello, {{lambda}}!", data);
 
-    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Hello, world!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Interpolation - Alternate Delimiters
@@ -73,7 +73,7 @@ fn test_spec_lambdas_interpolation_expansion() {
 
 //     let rv = rustache::render_text("{{= | | =}}\nHello, (|&lambda|)!", data);
 
-//     assert_eq!("Hello, (|planet| => world)!".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("Hello, (|planet| => world)!".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Interpolation - Multiple Calls
@@ -100,7 +100,7 @@ fn test_spec_lambdas_interpolation_multiple_calls() {
 
     let rv = rustache::render_text("{{lambda}} == {{{lambda}}} == {{lambda}}", data);
 
-    assert_eq!("1 == 2 == 3".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("1 == 2 == 3".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Escaping
@@ -123,7 +123,7 @@ fn test_spec_lambdas_escaping() {
 
     let rv = rustache::render_text("<{{lambda}}{{{lambda}}}", data);
 
-    assert_eq!("<&gt;>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("<&gt;>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Section
@@ -154,7 +154,7 @@ fn test_spec_lambdas_section() {
 
     let rv = rustache::render_text("<{{#lambda}}{{x}}{{/lambda}}>", data);
 
-    assert_eq!("<yes>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("<yes>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Section - Expansion
@@ -184,7 +184,7 @@ fn test_spec_lambdas_section_expansion() {
 
     let rv = rustache::render_text("<{{#lambda}}-{{/lambda}}>", data);
 
-    assert_eq!("<-Earth->".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("<-Earth->".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Section - Alternate Delimiters
@@ -213,7 +213,7 @@ fn test_spec_lambdas_section_expansion() {
 
 //     let rv = rustache::render_text_from_hb("{{= | | =}}<|#lambda|-|/lambda|>", data);
 
-//     assert_eq!("<-{{planet}} => Earth->".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("<-{{planet}} => Earth->".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Section - Multiple Calls
@@ -241,7 +241,7 @@ fn test_spec_lambdas_section_multiple_calls() {
 
     let rv = rustache::render_text("{{#lambda}}FILE{{/lambda}} != {{#lambda}}LINE{{/lambda}}", data);
 
-    assert_eq!("__FILE__ != __LINE__".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("__FILE__ != __LINE__".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Inverted Section
@@ -266,6 +266,6 @@ fn test_spec_lambdas_inverted_section() {
 
     let rv = rustache::render_text("<{{^lambda}}{{static}}{{/lambda}}>", data);
 
-    assert_eq!("<>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("<>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
diff --git a/tests/test_spec_partials.rs b/tests/test_spec_partials.rs
index 3c8496e..c59f350 100644
--- a/tests/test_spec_partials.rs
+++ b/tests/test_spec_partials.rs
@@ -14,7 +14,7 @@ fn test_spec_partials_basic_behavior() {
 
     let rv = rustache::render_text("\"{{>test_data/test_spec_partials_basic}}\"", data);
 
-    assert_eq!("\"from partial\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"from partial\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Failed Lookup
@@ -29,7 +29,7 @@ fn test_spec_partials_failed_lookup() {
 
     let rv = rustache::render_text("\"{{>text}}\"", data);
 
-    assert_eq!("\"\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Context
@@ -44,7 +44,7 @@ fn test_spec_partials_context() {
 
     let rv = rustache::render_text("\"{{>test_data/test_spec_partials_context}}\"", data);
 
-    assert_eq!("\"*content*\"".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("\"*content*\"".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Recursion
@@ -68,7 +68,7 @@ fn test_spec_partials_context() {
 
 //     let rv = rustache::render_text("{{>test_data/test_spec_partials_recursion}}", data);
 
-//     assert_eq!("X<Y<>>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("X<Y<>>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Surrounding Whitespace
@@ -83,7 +83,7 @@ fn test_spec_partials_surrounding_whitespace() {
 
     let rv = rustache::render_text("| {{>test_data/test_spec_partials_whitespace}} |", data);
 
-    assert_eq!("| \t|\t |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| \t|\t |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Inline Indentation
@@ -98,7 +98,7 @@ fn test_spec_partials_inline_indentation() {
 
     let rv = rustache::render_text("  {{data}}  {{> test_data/test_spec_partials_inline_indentation}}\n", data);
 
-    assert_eq!("  |  >\n>\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  |  >\n>\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Standalone Line Endings
@@ -113,7 +113,7 @@ fn test_spec_partials_inline_indentation() {
 
 //     let rv = rustache::render_text("|\r\n{{>partial}}\r\n|", data);
 
-//     assert_eq!("|\r\n>|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("|\r\n>|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Standalone Without Previous Line
@@ -128,7 +128,7 @@ fn test_spec_partials_standalone_without_previous_line() {
 
     let rv = rustache::render_text("  {{>test_data/test_spec_partials_standalone_without_previous_line}}\n>", data);
 
-    assert_eq!("  >\n>\n>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("  >\n>\n>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Standalone Without Newline
@@ -143,7 +143,7 @@ fn test_spec_partials_standalone_without_newline() {
 
     let rv = rustache::render_text(">\n  {{>test_data/test_spec_partials_standalone_without_newline}}", data);
 
-    assert_eq!(">\n  >\n>".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!(">\n  >\n>".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Standalone Indentation
@@ -171,7 +171,7 @@ fn test_spec_partials_standalone_without_newline() {
 
 //     let rv = rustache::render_text("|\n\\\n {{>test_data/test_spec_partials_standalone_indentation}}\n/\n", data);
 
-//     assert_eq!("|\n\\\n |\n <\n ->\n |\n/\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("|\n\\\n |\n <\n ->\n |\n/\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Padding Whitespace
@@ -187,5 +187,5 @@ fn test_spec_partials_padding_whitespace() {
 
     let rv = rustache::render_text("|{{> test_data/test_spec_partials_padding_whitespace }}|", data);
 
-    assert_eq!("|[]|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|[]|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
diff --git a/tests/test_spec_sections.rs b/tests/test_spec_sections.rs
index 786e879..297647f 100644
--- a/tests/test_spec_sections.rs
+++ b/tests/test_spec_sections.rs
@@ -14,7 +14,7 @@ fn test_spec_sections_truthy_should_render_contents() {
 
     let rv = rustache::render_text("{{#boolean}}This should be rendered.{{/boolean}}", data);
 
-    assert_eq!("This should be rendered.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("This should be rendered.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Falsy
@@ -29,7 +29,7 @@ fn test_spec_sections_falsy_should_not_render_contents() {
 
     let rv = rustache::render_text("{{#boolean}}This should not be rendered.{{/boolean}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Context
@@ -47,7 +47,7 @@ fn test_spec_sections_objects_and_hashes_should_be_pushed_onto_context_stack() {
 
     let rv = rustache::render_text("{{#context}}Hi {{name}}.{{/context}}", data);
 
-    assert_eq!("Hi Joe.".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("Hi Joe.".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 // - name: Deeply Nested Contexts
@@ -142,7 +142,7 @@ fn test_spec_sections_objects_and_hashes_should_be_pushed_onto_context_stack() {
 //                 12321
 //                 121
 //                 1".to_string(),
-//                 String::from_utf8(rv.unwrap().unwrap()).unwrap()
+//                 String::from_utf8(rv.unwrap().into_inner()).unwrap()
 //               );
 // }
 
@@ -172,7 +172,7 @@ fn test_spec_sections_list_items_are_iterated() {
 
     let rv = rustache::render_text("{{#list}}{{item}}{{/list}}", data);
 
-    assert_eq!("123".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("123".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Empty List
@@ -189,7 +189,7 @@ fn test_spec_sections_empty_lists_behave_like_falsy_values() {
 
     let rv = rustache::render_text("{{#list}}Yay lists!{{/list}}", data);
 
-    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Doubled
@@ -227,7 +227,7 @@ fn test_spec_sections_empty_lists_behave_like_falsy_values() {
 //     assert_eq!("* first
 //                 * second
 //                 * third".to_string(),
-//                 String::from_utf8(rv.unwrap().unwrap()).unwrap()
+//                 String::from_utf8(rv.unwrap().into_inner()).unwrap()
 //               );
 // }
 
@@ -243,7 +243,7 @@ fn test_spec_sections_nested_truthy_contents_render() {
 
     let rv = rustache::render_text("| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", data);
 
-    assert_eq!("| A B C D E |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| A B C D E |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Nested (Falsy)
@@ -258,7 +258,7 @@ fn test_spec_sections_nested_falsy_contents_do_not_render() {
 
     let rv = rustache::render_text("| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |", data);
 
-    assert_eq!("| A  E |".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("| A  E |".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Context Misses
@@ -272,7 +272,7 @@ fn test_spec_sections_failed_context_lookups_are_falsy() {
 
     let rv = rustache::render_text("[{{#missing}}Found key 'missing'!{{/missing}}]", data);
 
-    assert_eq!("[]".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("[]".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Implicit Iterator - String
@@ -295,7 +295,7 @@ fn test_spec_sections_failed_context_lookups_are_falsy() {
 
 // let rv = rustache::render_text("{{#list}}({{.}}){{/list}}", data);
 
-//     assert_eq!("(a)(b)(c)(d)(e)".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("(a)(b)(c)(d)(e)".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Implicit Iterator - Integer
@@ -318,7 +318,7 @@ fn test_spec_sections_failed_context_lookups_are_falsy() {
 
 //     let rv = rustache::render_text("{{#list}}({{.}}){{/list}}", data);
 
-//     assert_eq!("(1)(2)(3)(4)(5)".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("(1)(2)(3)(4)(5)".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Implicit Iterator - Decimal
@@ -341,7 +341,7 @@ fn test_spec_sections_failed_context_lookups_are_falsy() {
 
 //     let rv = rustache::render_text("{{#list}}({{.}}){{/list}}", data);
 
-//     assert_eq!("(1.1)(2.2)(3.3)(4.4)(5.5)".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("(1.1)(2.2)(3.3)(4.4)(5.5)".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Dotted Names - Truthy
@@ -362,7 +362,7 @@ fn test_spec_sections_failed_context_lookups_are_falsy() {
 
 //     let rv = rustache::render_text("'{{#a.b.c}}Here{{/a.b.c}}' == 'Here'", data);
 
-//     assert_eq!("'Here' == 'Here'".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("'Here' == 'Here'".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Dotted Names - Falsy
@@ -383,7 +383,7 @@ fn test_spec_sections_falsy_dotted_names_are_not_valid_section_tags() {
 
     let rv = rustache::render_text("'{{#a.b.c}}Here{{/a.b.c}}' == ''", data);
 
-    assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Dotted Names - Broken Chains
@@ -400,7 +400,7 @@ fn test_spec_sections_unresolved_dotted_names_are_not_valid_section_tags() {
 
     let rv = rustache::render_text("'{{#a.b.c}}Here{{/a.b.c}}' == ''", data);
 
-    assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("'' == ''".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Surrounding Whitespace
@@ -415,7 +415,7 @@ fn test_spec_sections_do_not_alter_surrounding_whitespace() {
 
     let rv = rustache::render_text(" | {{#boolean}}\t|\t{{/boolean}} | \n", data);
 
-    assert_eq!(" | \t|\t | \n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!(" | \t|\t | \n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Internal Whitespace
@@ -430,7 +430,7 @@ fn test_spec_sections_do_not_alter_surrounding_whitespace() {
 
 //     let rv = rustache::render_text(" | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n", data);
 
-//     assert_eq!(" |  \n  | \n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!(" |  \n  | \n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Indented Inline Sections
@@ -445,7 +445,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 
     let rv = rustache::render_text(" {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n", data);
 
-    assert_eq!(" YES\n GOOD\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!(" YES\n GOOD\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }
 
 //   - name: Standalone Lines
@@ -480,7 +480,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 //                 | This Is
 //                 |
 //                 | A Line".to_string(),
-//                 String::from_utf8(rv.unwrap().unwrap()).unwrap()
+//                 String::from_utf8(rv.unwrap().into_inner()).unwrap()
 //               );
 // }
 
@@ -516,7 +516,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 //                 | This Is
 //                 |
 //                 | A Line".to_string(),
-//                 String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//                 String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Standalone Line Endings
@@ -531,7 +531,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 
 //     let rv = rustache::render_text("|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|", data);
 
-//     assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("|\r\n|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Standalone Without Previous Line
@@ -546,7 +546,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 
 //     let rv = rustache::render_text("  {{#boolean}}\n#{{/boolean}}\n/", data);
 
-//     assert_eq!("#\n/".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("#\n/".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Standalone Without Newline
@@ -561,7 +561,7 @@ fn test_spec_sections_single_line_sections_do_not_alter_surrounding_whitespace()
 
 //     let rv = rustache::render_text("#{{#boolean}}\n/\n  {{/boolean}}", data);
 
-//     assert_eq!("#\n/\n".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+//     assert_eq!("#\n/\n".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 // }
 
 //   - name: Padding
@@ -576,5 +576,5 @@ fn test_spec_sections_superfluous_tag_whitespace_is_ignored() {
 
     let rv = rustache::render_text("|{{# boolean }}={{/ boolean }}|", data);
 
-    assert_eq!("|=|".to_string(), String::from_utf8(rv.unwrap().unwrap()).unwrap());
+    assert_eq!("|=|".to_string(), String::from_utf8(rv.unwrap().into_inner()).unwrap());
 }