Repository: Marwes/combine (language: rust)

Issue:
Document impl trait usage 
Hi @Marwes,

In #134 you've mentioned that `impl Trait` simplifies parsers a bit. Since it's already stable can you elaborate/add examples for it?


Discussion / hints:
The examples have already been updated https://github.com/Marwes/combine/tree/master/examples but it seems I missed the example at the root of the docs https://docs.rs/combine/3.3.0/combine/#examples . Is there anywhere else you were thinking of?
Yes, updating example in the root of the docs would be great. Sorry, forgot to take a look at the examples dir :)

Fix patch:
diff --git a/benches/http.rs b/benches/http.rs
index 4fe16c68..4abff343 100644
--- a/benches/http.rs
+++ b/benches/http.rs
@@ -9,7 +9,7 @@ use std::fmt;
 
 use combine::range::{range, take_while1};
 use combine::stream::easy;
-use combine::{many, token, ParseError, Parser, RangeStream, many1};
+use combine::{many, many1, token, ParseError, Parser, RangeStream};
 
 #[derive(Debug)]
 struct Request<'a> {
diff --git a/benches/json.rs b/benches/json.rs
index 50fc9a24..ed28d0e9 100644
--- a/benches/json.rs
+++ b/benches/json.rs
@@ -8,25 +8,25 @@ extern crate bencher;
 extern crate combine;
 
 use std::collections::HashMap;
-use std::io::Read;
 use std::fs::File;
+use std::io::Read;
 use std::path::Path;
 
 use bencher::{black_box, Bencher};
 
+use combine::error::{Consumed, ParseError};
 use combine::stream::buffered::BufferedStream;
 use combine::{Parser, Stream, StreamOnce};
-use combine::error::{Consumed, ParseError};
 
 use combine::parser::char::{char, digit, spaces, string};
-use combine::parser::item::{any, satisfy, satisfy_map};
-use combine::parser::sequence::between;
-use combine::parser::repeat::{many, sep_by, many1};
 use combine::parser::choice::{choice, optional};
 use combine::parser::function::parser;
+use combine::parser::item::{any, satisfy, satisfy_map};
+use combine::parser::repeat::{many, many1, sep_by};
+use combine::parser::sequence::between;
 
-use combine::stream::IteratorStream;
 use combine::stream::state::{SourcePosition, State};
+use combine::stream::IteratorStream;
 
 #[derive(PartialEq, Debug)]
 enum Value {
diff --git a/benches/mp4.rs b/benches/mp4.rs
index b58a0bef..a415d7ca 100644
--- a/benches/mp4.rs
+++ b/benches/mp4.rs
@@ -7,15 +7,15 @@ extern crate combine;
 
 use bencher::{black_box, Bencher};
 
-use std::str::from_utf8;
 use std::fs::File;
 use std::io::Read;
+use std::str::from_utf8;
 
 use byteorder::{BigEndian, ByteOrder};
 
-use combine::*;
 use combine::range::{range, take};
 use combine::stream::easy::ParseError;
+use combine::*;
 
 #[derive(Clone, PartialEq, Eq, Debug)]
 struct FileType<'a> {
diff --git a/examples/async.rs b/examples/async.rs
index f610d89b..1c7d287f 100644
--- a/examples/async.rs
+++ b/examples/async.rs
@@ -7,22 +7,22 @@ extern crate futures;
 extern crate partial_io;
 extern crate tokio_io;
 
-use std::rc::Rc;
 use std::cell::Cell;
-use std::str;
 use std::io::Cursor;
+use std::rc::Rc;
+use std::str;
 
 use bytes::BytesMut;
 
 use tokio_io::codec::Decoder;
 
-use combine::error::{ParseError, StreamError};
-use combine::stream::{PartialStream, RangeStream, StreamErrorFor};
 use combine::combinator::{any_partial_state, AnyPartialState};
+use combine::error::{ParseError, StreamError};
+use combine::parser::byte::digit;
 use combine::parser::range::{range, recognize, take};
-use combine::{skip_many, Parser, skip_many1};
 use combine::stream::easy;
-use combine::parser::byte::digit;
+use combine::stream::{PartialStream, RangeStream, StreamErrorFor};
+use combine::{skip_many, skip_many1, Parser};
 
 pub struct LanguageServerDecoder {
     state: AnyPartialState,
@@ -98,11 +98,12 @@ impl Decoder for LanguageServerDecoder {
             // Since err contains references into `src` we must replace these before
             // we can return an error or call `split_to` to remove the input we
             // just consumed
-            let err = err.map_range(|r| {
-                str::from_utf8(r)
-                    .ok()
-                    .map_or_else(|| format!("{:?}", r), |s| s.to_string())
-            }).map_position(|p| p.translate_position(&src[..]));
+            let err =
+                err.map_range(|r| {
+                    str::from_utf8(r)
+                        .ok()
+                        .map_or_else(|| format!("{:?}", r), |s| s.to_string())
+                }).map_position(|p| p.translate_position(&src[..]));
             format!("{}\nIn input: `{}`", err, str::from_utf8(src).unwrap())
         })?;
 
@@ -139,8 +140,8 @@ impl Decoder for LanguageServerDecoder {
 
 fn main() {
     use futures::{Future, Stream};
-    use tokio_io::codec::FramedRead;
     use partial_io::{PartialAsyncRead, PartialOp};
+    use tokio_io::codec::FramedRead;
 
     let input = "Content-Length: 6\r\n\
                  \r\n\
diff --git a/examples/date.rs b/examples/date.rs
index dddd98f6..46192f7c 100644
--- a/examples/date.rs
+++ b/examples/date.rs
@@ -7,15 +7,15 @@ use std::fmt;
 use std::fs::File;
 use std::io::{self, Read};
 
+use combine::error::ParseError;
 use combine::parser::char::{char, digit};
-use combine::{choice, many, optional, Parser, Stream};
 use combine::stream::state::State;
-use combine::error::ParseError;
+use combine::{choice, many, optional, Parser, Stream};
 
-#[cfg(feature = "std")]
-use combine::stream::state::SourcePosition;
 #[cfg(feature = "std")]
 use combine::stream::easy;
+#[cfg(feature = "std")]
+use combine::stream::state::SourcePosition;
 
 enum Error<E> {
     Io(io::Error),
diff --git a/examples/ini.rs b/examples/ini.rs
index 5b2f8e78..925b13f6 100644
--- a/examples/ini.rs
+++ b/examples/ini.rs
@@ -2,19 +2,19 @@
 extern crate combine;
 
 use std::collections::HashMap;
-use std::fmt;
 use std::env;
+use std::fmt;
 use std::fs::File;
 use std::io::{self, Read};
 
-use combine::*;
 use combine::parser::char::space;
 use combine::stream::state::State;
+use combine::*;
 
-#[cfg(feature = "std")]
-use combine::stream::state::SourcePosition;
 #[cfg(feature = "std")]
 use combine::stream::easy;
+#[cfg(feature = "std")]
+use combine::stream::state::SourcePosition;
 
 enum Error<E> {
     Io(io::Error),
diff --git a/examples/number.rs b/examples/number.rs
index bd372912..41aa8ef2 100644
--- a/examples/number.rs
+++ b/examples/number.rs
@@ -1,11 +1,11 @@
 extern crate combine;
 
-use combine::parser::range::recognize;
-use combine::parser::repeat::{skip_many, skip_many1};
+use combine::error::UnexpectedParse;
+use combine::parser::byte::digit;
 use combine::parser::choice::optional;
 use combine::parser::item::item;
-use combine::parser::byte::digit;
-use combine::error::UnexpectedParse;
+use combine::parser::range::recognize;
+use combine::parser::repeat::{skip_many, skip_many1};
 use combine::Parser;
 
 fn main() {
diff --git a/examples/readme.rs b/examples/readme.rs
index d74ca11d..ae1a8829 100644
--- a/examples/readme.rs
+++ b/examples/readme.rs
@@ -1,6 +1,6 @@
 extern crate combine;
-use combine::{sep_by, Parser, many1};
 use combine::parser::char::{letter, space};
+use combine::{many1, sep_by, Parser};
 
 #[test]
 fn readme() {
diff --git a/rustfmt.toml b/rustfmt.toml
index f27449ee..e6067ba1 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,2 +1,1 @@
 newline_style = "Native"
-error_on_line_overflow_comments = false
diff --git a/src/lib.rs b/src/lib.rs
index 2755e913..51ed6d6e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -93,8 +93,8 @@
 //! #[macro_use]
 //! extern crate combine;
 //! use combine::parser::char::{char, letter, spaces};
-//! use combine::{between, many1, parser, sep_by, Parser};
-//! use combine::error::ParseResult;
+//! use combine::{between, choice, many1, parser, sep_by, Parser};
+//! use combine::error::{ParseError, ParseResult};
 //! use combine::stream::{Stream, Positioned};
 //! use combine::stream::state::State;
 //!
@@ -105,12 +105,11 @@
 //!     Pair(Box<Expr>, Box<Expr>)
 //! }
 //!
-//! // The `parser!` macro can be used to define parser producing functions in most cases
-//! // (for more advanced uses standalone functions or explicit implementation of `Parser`
-//! // can be done to handle parsing)
-//! parser!{
-//!    fn expr[I]()(I) -> Expr
-//!     where [I: Stream<Item=char>]
+//! // `impl Parser` can be used to create reusable parsers with zero overhead
+//! fn expr_<I>() -> impl Parser<Input = I, Output = Expr>
+//!     where I: Stream<Item = char>,
+//!           // Necessary due to rust-lang/rust#24159
+//!           I::Error: ParseError<I::Item, I::Range, I::Position>,
 //! {
 //!     let word = many1(letter());
 //!
@@ -129,11 +128,27 @@
 //!                 lex_char(')'))
 //!                    .map(|t| Expr::Pair(Box::new(t.1), Box::new(t.3)));
 //!
-//!     word.map(Expr::Id)
-//!         .or(array.map(Expr::Array))
-//!         .or(pair)
+//!     choice((
+//!         word.map(Expr::Id),
+//!         array.map(Expr::Array),
+//!         pair,
+//!     ))
 //!         .skip(spaces())
 //! }
+//!
+//! // As this expression parser needs to be able to call itself recursively `impl Parser` can't
+//! // be used on its own as that would cause an infinitely large type. We can avoid this by using
+//! // the `parser!` macro which erases the inner type and the size of that type entirely which
+//! // lets it be used recursively.
+//! //
+//! // (This macro does not use `impl Trait` which means it can be used in rust < 1.26 as well to
+//! // emulate `impl Parser`)
+//! parser!{
+//!     fn expr[I]()(I) -> Expr
+//!     where [I: Stream<Item = char>]
+//!     {
+//!         expr_()
+//!     }
 //! }
 //!
 //! fn main() {
@@ -169,19 +184,20 @@
 #![cfg_attr(feature = "cargo-clippy", allow(inline_always))]
 #![cfg_attr(not(feature = "std"), no_std)]
 
-#[doc(inline)]
-pub use parser::Parser;
 #[doc(inline)]
 pub use error::{ConsumedResult, ParseError, ParseResult};
 #[doc(inline)]
+pub use parser::Parser;
+#[doc(inline)]
 pub use stream::{Positioned, RangeStream, RangeStreamOnce, Stream, StreamOnce};
 
 #[doc(inline)]
-pub use combinator::{any, between, count, count_min_max, env_parser, eof, look_ahead, many,
-                     none_of, not_followed_by, one_of, optional, parser, position, satisfy,
-                     satisfy_map, sep_by, sep_end_by, skip_count, skip_count_min_max, skip_many,
-                     token, tokens, try, unexpected, value, chainl1, chainr1, many1, sep_by1,
-                     sep_end_by1, skip_many1};
+pub use combinator::{
+    any, between, chainl1, chainr1, count, count_min_max, env_parser, eof, look_ahead, many, many1,
+    none_of, not_followed_by, one_of, optional, parser, position, satisfy, satisfy_map, sep_by,
+    sep_by1, sep_end_by, sep_end_by1, skip_count, skip_count_min_max, skip_many, skip_many1, token,
+    tokens, try, unexpected, value,
+};
 #[doc(inline)]
 pub use parser::choice::choice;
 
@@ -533,14 +549,15 @@ macro_rules! parser {
 #[doc(hidden)]
 #[macro_export]
 macro_rules! combine_parse_partial {
-    ((()) $input: ident $state: ident $parser: block) => { {
+    ((()) $input:ident $state:ident $parser:block) => {{
         let _ = $state;
         let ref mut state = Default::default();
         $parser.parse_partial($input, state)
-    } };
-    (($ignored: ty) $input: ident $state: ident $parser: block) => {
+    }};
+    (($ignored:ty) $input:ident $state:ident $parser:block) => {
+
         $parser.parse_partial($input, $state)
-    }
+    };
 }
 
 #[doc(hidden)]
@@ -648,10 +665,10 @@ extern crate unreachable;
 // Public but hidden to be accessible in macros
 #[doc(hidden)]
 pub mod lib {
-    #[cfg(feature = "std")]
-    pub use std::*;
     #[cfg(not(feature = "std"))]
     pub use core::*;
+    #[cfg(feature = "std")]
+    pub use std::*;
 }
 
 #[cfg(feature = "std")]
@@ -668,23 +685,25 @@ pub mod parser;
 
 /// Re-exported parsers for compatibility with older versions
 #[doc(hidden)]
-#[deprecated(since = "3.0.0",
-             note = "Please import parsers from the `parser` module and its submodules instead")]
+#[deprecated(
+    since = "3.0.0",
+    note = "Please import parsers from the `parser` module and its submodules instead"
+)]
 pub mod combinator {
-    #[doc(inline)]
-    pub use parser::sequence::*;
     #[doc(inline)]
     pub use parser::choice::*;
     #[doc(inline)]
-    pub use parser::item::*;
-    #[doc(inline)]
-    pub use parser::repeat::*;
+    pub use parser::combinator::*;
     #[doc(inline)]
     pub use parser::error::*;
     #[doc(inline)]
     pub use parser::function::*;
     #[doc(inline)]
-    pub use parser::combinator::*;
+    pub use parser::item::*;
+    #[doc(inline)]
+    pub use parser::repeat::*;
+    #[doc(inline)]
+    pub use parser::sequence::*;
 }
 
 #[doc(hidden)]
@@ -744,10 +763,10 @@ mod tests {
 
 #[cfg(all(feature = "std", test))]
 mod std_tests {
-    use super::*;
+    use super::easy::Error;
     use super::error::Consumed;
     use super::stream::IteratorStream;
-    use super::easy::Error;
+    use super::*;
 
     use parser::char::{alpha_num, char, digit, letter, spaces, string};
     use stream::easy;
@@ -983,8 +1002,8 @@ mod std_tests {
 
     #[test]
     fn std_error() {
-        use std::fmt;
         use std::error::Error as StdError;
+        use std::fmt;
         #[derive(Debug)]
         struct Error;
         impl fmt::Display for Error {
@@ -1016,8 +1035,8 @@ mod std_tests {
         // appreciate this.  For technical reasons this is pretty janky; see the discussion in
         // https://github.com/Marwes/combine/issues/86, and excuse the test with significant
         // boilerplate!
-        use std::fmt;
         use std::error::Error as StdError;
+        use std::fmt;
 
         #[derive(Clone, PartialEq, Debug)]
         struct CloneOnly(String);
diff --git a/src/parser/byte.rs b/src/parser/byte.rs
index 30a3b3d1..6a3896de 100644
--- a/src/parser/byte.rs
+++ b/src/parser/byte.rs
@@ -5,12 +5,12 @@ use lib::marker::PhantomData;
 
 use self::ascii::AsciiChar;
 
-use Parser;
-use parser::ParseMode;
 use combinator::{satisfy, skip_many, token, tokens, Expected, Satisfy, SkipMany, Token};
-use parser::sequence::With;
 use error::{ConsumedResult, Info, ParseError, StreamError, Tracked};
+use parser::sequence::With;
+use parser::ParseMode;
 use stream::{uncons_range, FullRangeStream, RangeStream, Stream, StreamOnce};
+use Parser;
 
 use error::FastResult::*;
 
@@ -35,12 +35,12 @@ where
 impl_token_parser! { Digit(), u8, Expected<Satisfy<I, fn (u8) -> bool>> }
 
 macro_rules! byte_parser {
-    ($name: ident, $ty : ident, $f : ident) => ({
-        let f = static_fn!((c, u8) -> bool {
-            AsciiChar::from(c).map(|c| c.$f()).unwrap_or(false)
-        });
+    ($name:ident, $ty:ident, $f:ident) => {{
+        let f = static_fn!{
+            (c, u8) -> bool { AsciiChar::from(c).map(|c| c.$f()).unwrap_or(false) }
+        };
         $ty(satisfy(f).expected(stringify!($name)), PhantomData)
-    })
+    }};
 }
 
 /// Parses a base-10 digit (0–9).
@@ -727,9 +727,9 @@ pub mod num {
     #[cfg(test)]
     mod tests {
         use super::*;
+        use stream::buffered::BufferedStream;
         use stream::state::State;
         use stream::IteratorStream;
-        use stream::buffered::BufferedStream;
 
         #[test]
         fn no_rangestream() {
diff --git a/src/parser/char.rs b/src/parser/char.rs
index 6d40b276..3fd4c1a1 100644
--- a/src/parser/char.rs
+++ b/src/parser/char.rs
@@ -1,11 +1,11 @@
 //! Module containing parsers specialized on character streams.
 
-use Parser;
-use error::{ConsumedResult, ParseError, Tracked};
-use stream::{Stream, StreamOnce};
 use combinator::{satisfy, skip_many, token, tokens, Expected, Satisfy, SkipMany, Token};
-use parser::sequence::With;
+use error::{ConsumedResult, ParseError, Tracked};
 use lib::marker::PhantomData;
+use parser::sequence::With;
+use stream::{Stream, StreamOnce};
+use Parser;
 
 /// Parses a character and succeeds if the character is equal to `c`.
 ///
diff --git a/src/parser/choice.rs b/src/parser/choice.rs
index a98080bd..f0725045 100644
--- a/src/parser/choice.rs
+++ b/src/parser/choice.rs
@@ -1,10 +1,10 @@
 //! Combinators which take one or more parsers and attempts to parse successfully with at least one
 //! of them.
-use {ErrorOffset, Parser, Stream, StreamOnce};
-use error::{ConsumedResult, ParseError, StreamError, Tracked};
 use error::FastResult::*;
+use error::{ConsumedResult, ParseError, StreamError, Tracked};
 use parser::ParseMode;
 use stream::Resetable;
+use {ErrorOffset, Parser, Stream, StreamOnce};
 
 /// Takes a number of parsers and tries to apply them each in order.
 /// Fails if all the parsers fails or if an applied parser consumes input before failing.
diff --git a/src/parser/combinator.rs b/src/parser/combinator.rs
index 7d18058e..a859487d 100644
--- a/src/parser/combinator.rs
+++ b/src/parser/combinator.rs
@@ -3,12 +3,12 @@
 use lib::marker::PhantomData;
 use lib::mem;
 
-use Parser;
 use error::{ConsumedResult, Info, ParseError, Tracked};
-use stream::{Positioned, Resetable, Stream, StreamOnce};
-use parser::ParseMode;
-use parser::item::value;
 use parser::error::unexpected;
+use parser::item::value;
+use parser::ParseMode;
+use stream::{Positioned, Resetable, Stream, StreamOnce};
+use Parser;
 
 use either::Either;
 
diff --git a/src/parser/error.rs b/src/parser/error.rs
index f57955bd..378bb633 100644
--- a/src/parser/error.rs
+++ b/src/parser/error.rs
@@ -2,9 +2,9 @@
 
 use lib::marker::PhantomData;
 
-use {Parser, Stream, StreamOnce};
-use parser::ParseMode;
 use error::{ConsumedResult, Info, ParseError, StreamError, Tracked};
+use parser::ParseMode;
+use {Parser, Stream, StreamOnce};
 
 use error::FastResult::*;
 
diff --git a/src/parser/function.rs b/src/parser/function.rs
index 4f1c8fe1..0c5fcfe3 100644
--- a/src/parser/function.rs
+++ b/src/parser/function.rs
@@ -2,9 +2,9 @@
 
 use lib::marker::PhantomData;
 
-use Parser;
 use error::{ConsumedResult, ParseResult};
 use stream::Stream;
+use Parser;
 
 impl<'a, I: Stream, O> Parser for FnMut(&mut I) -> ParseResult<O, I> + 'a {
     type Input = I;
diff --git a/src/parser/item.rs b/src/parser/item.rs
index d7eeb422..ae406d2e 100644
--- a/src/parser/item.rs
+++ b/src/parser/item.rs
@@ -2,9 +2,9 @@
 
 use lib::marker::PhantomData;
 
-use Parser;
-use stream::{uncons, Stream, StreamOnce};
 use error::{ConsumedResult, Info, ParseError, StreamError, Tracked};
+use stream::{uncons, Stream, StreamOnce};
+use Parser;
 
 use error::FastResult::*;
 
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index a1ba4c4b..71380cb0 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -4,15 +4,17 @@
 //! implementing all combine parsers.
 use either::Either;
 
-use ErrorOffset;
-use stream::{Resetable, Stream, StreamOnce};
-use error::{ConsumedResult, FastResult, Info, ParseError, ParseResult, Tracked};
+use combinator::{
+    and_then, expected, flat_map, map, message, then, then_partial, AndThen, Expected, FlatMap,
+    Iter, Map, Message, Then, ThenPartial,
+};
 use error::FastResult::*;
-use combinator::{and_then, expected, flat_map, map, message, then, then_partial, AndThen,
-                 Expected, FlatMap, Iter, Map, Message, Then, ThenPartial};
+use error::{ConsumedResult, FastResult, Info, ParseError, ParseResult, Tracked};
+use stream::{Resetable, Stream, StreamOnce};
+use ErrorOffset;
 
-use self::sequence::{skip, with, Skip, With};
 use self::choice::{or, Or};
+use self::sequence::{skip, with, Skip, With};
 
 /// Internal API. May break without a semver bump
 #[macro_export]
@@ -72,18 +74,18 @@ macro_rules! parse_mode {
     }
 }
 
-pub mod range;
 pub mod byte;
 pub mod char;
-pub mod item;
+pub mod choice;
+pub mod combinator;
 pub mod error;
 pub mod function;
-pub mod combinator;
-pub mod repeat;
-pub mod sequence;
-pub mod choice;
+pub mod item;
+pub mod range;
 #[cfg(feature = "regex")]
 pub mod regex;
+pub mod repeat;
+pub mod sequence;
 
 /// By implementing the `Parser` trait a type says that it can be used to parse an input stream
 /// into the type `Output`.
diff --git a/src/parser/range.rs b/src/parser/range.rs
index 749ad217..62be1998 100644
--- a/src/parser/range.rs
+++ b/src/parser/range.rs
@@ -2,12 +2,14 @@
 
 use lib::marker::PhantomData;
 
-use Parser;
-use stream::{uncons_range, uncons_while, uncons_while1, wrap_stream_error, RangeStream, RangeStreamOnce,
-             Resetable, StreamOnce};
-use error::{ConsumedResult, Info, ParseError, Tracked};
 use error::FastResult::*;
+use error::{ConsumedResult, Info, ParseError, Tracked};
 use parser::ParseMode;
+use stream::{
+    uncons_range, uncons_while, uncons_while1, wrap_stream_error, RangeStream, RangeStreamOnce,
+    Resetable, StreamOnce,
+};
+use Parser;
 
 pub struct Range<I>(I::Range)
 where
@@ -286,7 +288,7 @@ where
             mode,
             input,
             state,
-            &mut self.0, 
+            &mut self.0,
             |input, predicate| uncons_while(input, predicate),
             |input, predicate| uncons_while(input, predicate),
         )
@@ -343,7 +345,7 @@ where
             mode,
             input,
             state,
-            &mut self.0, 
+            &mut self.0,
             |input, predicate| uncons_while1(input, predicate),
             |input, predicate| uncons_while(input, predicate),
         )
diff --git a/src/parser/regex.rs b/src/parser/regex.rs
index a2534b23..b1e929bd 100644
--- a/src/parser/regex.rs
+++ b/src/parser/regex.rs
@@ -37,11 +37,11 @@ extern crate regex;
 use std::iter::FromIterator;
 use std::marker::PhantomData;
 
-use Parser;
-use error::{ConsumedResult, ParseError, StreamError, Tracked};
 use error::FastResult::*;
-use stream::{FullRangeStream, StreamOnce};
+use error::{ConsumedResult, ParseError, StreamError, Tracked};
 use parser::range::take;
+use stream::{FullRangeStream, StreamOnce};
+use Parser;
 
 struct First<T>(Option<T>);
 
diff --git a/src/parser/sequence.rs b/src/parser/sequence.rs
index 0d9a4e77..37db3f7c 100644
--- a/src/parser/sequence.rs
+++ b/src/parser/sequence.rs
@@ -1,11 +1,11 @@
 //! Combinators which take multiple parsers and applies them one after another.
 use lib::marker::PhantomData;
 
-use {ErrorOffset, Parser, Stream, StreamOnce};
-use parser::ParseMode;
-use error::{ConsumedResult, ParseError, StreamError, Tracked};
-use error::FastResult::*;
 use combinator::{ignore, Ignore};
+use error::FastResult::*;
+use error::{ConsumedResult, ParseError, StreamError, Tracked};
+use parser::ParseMode;
+use {ErrorOffset, Parser, Stream, StreamOnce};
 
 macro_rules! dispatch_on {
     ($i: expr, $f: expr;) => {
@@ -608,11 +608,8 @@ where
             mode.set_first();
         }
 
-        let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1).parse_consumed_mode(
-            mode,
-            input,
-            n_state,
-        );
+        let result = (self.1)(&mut n_parser_cache.as_mut().unwrap().1)
+            .parse_consumed_mode(mode, input, n_state);
         match result {
             EmptyOk(x) => {
                 let (consumed, _) = *n_parser_cache.as_ref().unwrap();
diff --git a/src/stream/easy.rs b/src/stream/easy.rs
index 7991e513..1115e2a1 100644
--- a/src/stream/easy.rs
+++ b/src/stream/easy.rs
@@ -84,8 +84,10 @@ use std::error::Error as StdError;
 use std::fmt;
 
 use error::{FastResult, Info as PrimitiveInfo, StreamError, Tracked};
-use stream::{FullRangeStream, Positioned, RangeStream, RangeStreamOnce, Resetable, StreamErrorFor,
-             StreamOnce};
+use stream::{
+    FullRangeStream, Positioned, RangeStream, RangeStreamOnce, Resetable, StreamErrorFor,
+    StreamOnce,
+};
 
 /// Enum holding error information. Variants are defined for `Stream::Item` and `Stream::Range` as
 /// well as string variants holding easy descriptions.
diff --git a/src/stream/mod.rs b/src/stream/mod.rs
index fd242cd1..bf592938 100644
--- a/src/stream/mod.rs
+++ b/src/stream/mod.rs
@@ -355,7 +355,6 @@ pub trait Range {
     }
 }
 
-
 fn str_uncons_while<'a, F>(slice: &mut &'a str, mut chars: Chars<'a>, mut f: F) -> &'a str
 where
     F: FnMut(char) -> bool,
@@ -408,14 +407,15 @@ impl<'a> RangeStreamOnce for &'a str {
     {
         let mut chars = self.chars();
         match chars.next() {
-            Some(c) => if !f(c) { return EmptyErr(Tracked::from(StringStreamError::UnexpectedParse)) },
+            Some(c) => if !f(c) {
+                return EmptyErr(Tracked::from(StringStreamError::UnexpectedParse));
+            },
             None => return EmptyErr(Tracked::from(StringStreamError::UnexpectedParse)),
         }
 
         ConsumedOk(str_uncons_while(self, chars, f))
     }
 
-
     #[inline]
     fn uncons_range(&mut self, size: usize) -> Result<&'a str, StreamErrorFor<Self>> {
         fn is_char_boundary(s: &str, index: usize) -> bool {
@@ -476,6 +476,7 @@ where
 
     macro_rules! check {
         () => {
+
             if !f(unsafe { slice.get_unchecked(i).clone() }) {
                 found = true;
                 break;
@@ -747,7 +748,6 @@ where
     }
 }
 
-
 fn slice_uncons_while_ref<'a, T, F>(slice: &mut &'a [T], mut i: usize, mut f: F) -> &'a [T]
 where
     F: FnMut(&'a T) -> bool,
@@ -757,6 +757,7 @@ where
 
     macro_rules! check {
         () => {
+
             if !f(unsafe { slice.get_unchecked(i) }) {
                 found = true;
                 break;
@@ -825,7 +826,6 @@ where
         ConsumedOk(slice_uncons_while_ref(&mut self.0, 1, f))
     }
 
-
     #[inline]
     fn distance(&self, end: &Self) -> usize {
         end.0.len() - self.0.len()
diff --git a/src/stream/state.rs b/src/stream/state.rs
index 6f105743..10b6167a 100644
--- a/src/stream/state.rs
+++ b/src/stream/state.rs
@@ -1,8 +1,10 @@
 use lib::fmt;
 
-use error::{ParseError, StreamError, FastResult};
-use stream::{FullRangeStream, IteratorStream, Positioned, RangeStreamOnce, Resetable, SliceStream,
-             StreamErrorFor, StreamOnce};
+use error::{FastResult, ParseError, StreamError};
+use stream::{
+    FullRangeStream, IteratorStream, Positioned, RangeStreamOnce, Resetable, SliceStream,
+    StreamErrorFor, StreamOnce,
+};
 
 #[cfg(feature = "std")]
 use stream::ReadStream;
@@ -272,7 +274,10 @@ where
     }
 
     #[inline]
-    fn uncons_while1<F>(&mut self, mut predicate: F) -> FastResult<Self::Range, StreamErrorFor<Self>>
+    fn uncons_while1<F>(
+        &mut self,
+        mut predicate: F,
+    ) -> FastResult<Self::Range, StreamErrorFor<Self>>
     where
         F: FnMut(Self::Item) -> bool,
     {
diff --git a/travis.sh b/travis.sh
index 9eefb7fe..de3e4d84 100755
--- a/travis.sh
+++ b/travis.sh
@@ -4,6 +4,7 @@ set -ex
 echo "TRAVIS_RUST_VERSION=$TRAVIS_RUST_VERSION"
 if [ "$TRAVIS_RUST_VERSION" == "1.20.0" ]; then
     cargo test --lib
+    cargo build --no-default-features
 else
     cargo build
     cargo test --features doc


Test patch:
diff --git a/tests/buffered_stream.rs b/tests/buffered_stream.rs
index 0e7d0ff9..71066334 100644
--- a/tests/buffered_stream.rs
+++ b/tests/buffered_stream.rs
@@ -1,11 +1,11 @@
 #![cfg(feature = "std")]
 extern crate combine;
-use combine::stream::IteratorStream;
+use combine::parser::char::{char, digit, spaces, string};
 use combine::stream::buffered::BufferedStream;
 use combine::stream::easy::{self, Error};
-use combine::parser::char::{char, digit, spaces, string};
-use combine::{choice, many, sep_by, try, Parser, Positioned, many1};
 use combine::stream::state::State;
+use combine::stream::IteratorStream;
+use combine::{choice, many, many1, sep_by, try, Parser, Positioned};
 
 #[test]
 fn shared_stream_buffer() {
diff --git a/tests/parser.rs b/tests/parser.rs
index d82e1516..ab6035cd 100644
--- a/tests/parser.rs
+++ b/tests/parser.rs
@@ -1,13 +1,13 @@
 extern crate combine;
 
-use combine::Parser;
 use combine::parser::char::{digit, letter};
-use combine::parser::range::range;
-use combine::parser::item::{any, eof, token, value, Token};
-use combine::parser::repeat::{count_min_max, sep_by, sep_end_by1};
 use combine::parser::choice::{choice, optional};
 use combine::parser::combinator::{no_partial, not_followed_by, try};
 use combine::parser::error::unexpected;
+use combine::parser::item::{any, eof, token, value, Token};
+use combine::parser::range::range;
+use combine::parser::repeat::{count_min_max, sep_by, sep_end_by1};
+use combine::Parser;
 
 #[test]
 fn choice_empty() {
@@ -43,10 +43,10 @@ fn not_followed_by_does_not_consume_any_input() {
 #[cfg(feature = "std")]
 mod tests_std {
     use super::*;
-    use combine::Parser;
-    use combine::stream::easy::{Error, Errors, ParseError};
     use combine::parser::char::{char, digit, letter};
+    use combine::stream::easy::{Error, Errors, ParseError};
     use combine::stream::state::{SourcePosition, State};
+    use combine::Parser;
 
     #[derive(Clone, PartialEq, Debug)]
     struct CloneOnly {