diff --git a/.travis.yml b/.travis.yml
index 053ba1f5..d32bf418 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,7 @@ matrix:
         - rustup target add wasm32-unknown-unknown
         - cargo build --target=wasm32-unknown-unknown
     # minimum rustc version
-    - rust: 1.20.0
+    - rust: 1.39.0
       script: cargo build
 
 script:
diff --git a/Cargo.toml b/Cargo.toml
index 6e6608ea..aa2e2a8c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ name = "http"
 # - Update html_root_url in lib.rs.
 # - Update CHANGELOG.md.
 # - Create git tag
-version = "0.1.20"
+version = "0.2.0-alpha.0"
 readme = "README.md"
 documentation = "https://docs.rs/http"
 repository = "https://github.com/hyperium/http"
@@ -19,16 +19,20 @@ A set of types for representing HTTP requests and responses.
 """
 keywords = ["http"]
 categories = ["web-programming"]
+edition = "2018"
+
+# 0.2.x isn't ready just yet
+publish = false
 
 [dependencies]
-bytes = "0.4"
+bytes = "0.5"
 fnv = "1.0.5"
 itoa = "0.4.1"
 
 [dev-dependencies]
 indexmap = "1.0"
-quickcheck = "0.6"
-rand = "0.4"
+quickcheck = "0.9.0"
+rand = "0.7.0"
 seahash = "3.0.5"
 serde = "1.0"
 serde_json = "1.0"
diff --git a/benches/header_map/basic.rs b/benches/header_map/basic.rs
index 4ce7ed62..078b89fb 100644
--- a/benches/header_map/basic.rs
+++ b/benches/header_map/basic.rs
@@ -2,13 +2,13 @@ macro_rules! bench {
     ($name:ident($map:ident, $b:ident) $body:expr) => {
         mod $name {
             #[allow(unused_imports)]
-            use test::{self, Bencher};
-            use seahash::SeaHasher;
+            use super::custom_hdr;
             use fnv::FnvHasher;
-            use std::hash::BuildHasherDefault;
             use http::header::*;
+            use seahash::SeaHasher;
+            use std::hash::BuildHasherDefault;
             #[allow(unused_imports)]
-            use super::custom_hdr;
+            use test::{self, Bencher};
 
             #[bench]
             fn header_map($b: &mut Bencher) {
@@ -25,7 +25,7 @@ macro_rules! bench {
 
             #[bench]
             fn vec_map($b: &mut Bencher) {
-                use vec_map::VecMap;
+                use crate::vec_map::VecMap;
 
                 let $map = || VecMap::with_capacity(0);
                 $body
@@ -208,7 +208,6 @@ bench!(set_10_get_1_custom_short(new_map, b) {
     })
 });
 
-
 bench!(set_10_get_1_custom_med(new_map, b) {
     let hdrs = super::med_custom_hdr(10);
 
@@ -474,38 +473,48 @@ bench!(hn_hdrs_set_11_get_with_miss(new_map, b) {
 use http::header::*;
 
 fn custom_hdr(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("x-custom-{}", i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("x-custom-{}", i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 fn med_custom_hdr(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("content-length-{}", i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("content-length-{}", i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 fn long_custom_hdr(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("access-control-allow-headers-{}", i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("access-control-allow-headers-{}", i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 fn very_long_custom_hdr(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("access-control-allow-access-control-allow-headers-{}", i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("access-control-allow-access-control-allow-headers-{}", i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 fn custom_std(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 const STD: &'static [HeaderName] = &[
diff --git a/benches/header_map/mod.rs b/benches/header_map/mod.rs
index 50a97f7a..d0317b33 100644
--- a/benches/header_map/mod.rs
+++ b/benches/header_map/mod.rs
@@ -1,10 +1,6 @@
 #![feature(test)]
 
-extern crate http;
 extern crate test;
-extern crate indexmap;
-extern crate seahash;
-extern crate fnv;
 
 mod basic;
 mod vec_map;
diff --git a/benches/header_map/vec_map.rs b/benches/header_map/vec_map.rs
index 995e8062..1a3eb15d 100644
--- a/benches/header_map/vec_map.rs
+++ b/benches/header_map/vec_map.rs
@@ -9,7 +9,7 @@ impl<K: PartialEq, V> VecMap<K, V> {
     #[inline]
     pub fn with_capacity(cap: usize) -> VecMap<K, V> {
         VecMap {
-            vec: Vec::with_capacity(cap)
+            vec: Vec::with_capacity(cap),
         }
     }
 
@@ -17,12 +17,12 @@ impl<K: PartialEq, V> VecMap<K, V> {
     pub fn insert(&mut self, key: K, value: V) {
         match self.find(&key) {
             Some(pos) => self.vec[pos] = (key, value),
-            None => self.vec.push((key, value))
+            None => self.vec.push((key, value)),
         }
     }
 
     #[inline]
-    pub fn entry(&mut self, key: K) -> Entry<K, V> {
+    pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
         match self.find(&key) {
             Some(pos) => Entry::Occupied(OccupiedEntry {
                 vec: self,
@@ -31,7 +31,7 @@ impl<K: PartialEq, V> VecMap<K, V> {
             None => Entry::Vacant(VacantEntry {
                 vec: self,
                 key: key,
-            })
+            }),
         }
     }
 
@@ -51,15 +51,19 @@ impl<K: PartialEq, V> VecMap<K, V> {
     }
 
     #[inline]
-    pub fn len(&self) -> usize { self.vec.len() }
+    pub fn len(&self) -> usize {
+        self.vec.len()
+    }
 
     #[inline]
-    pub fn iter(&self) -> ::std::slice::Iter<(K, V)> {
+    pub fn iter(&self) -> ::std::slice::Iter<'_, (K, V)> {
         self.vec.iter()
     }
     #[inline]
     pub fn remove<K2: PartialEq<K> + ?Sized>(&mut self, key: &K2) -> Option<V> {
-        self.find(key).map(|pos| self.vec.remove(pos)).map(|(_, v)| v)
+        self.find(key)
+            .map(|pos| self.vec.remove(pos))
+            .map(|(_, v)| v)
     }
     #[inline]
     pub fn clear(&mut self) {
@@ -74,10 +78,10 @@ impl<K: PartialEq, V> VecMap<K, V> {
 
 pub enum Entry<'a, K: 'a, V: 'a> {
     Vacant(VacantEntry<'a, K, V>),
-    Occupied(OccupiedEntry<'a, K, V>)
+    Occupied(OccupiedEntry<'a, K, V>),
 }
 
-pub struct VacantEntry<'a, K: 'a, V: 'a> {
+pub struct VacantEntry<'a, K, V> {
     vec: &'a mut VecMap<K, V>,
     key: K,
 }
@@ -91,7 +95,7 @@ impl<'a, K, V> VacantEntry<'a, K, V> {
     }
 }
 
-pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
+pub struct OccupiedEntry<'a, K, V> {
     vec: &'a mut VecMap<K, V>,
     pos: usize,
 }
diff --git a/benches/header_value.rs b/benches/header_value.rs
index aea0b20d..df5e9dab 100644
--- a/benches/header_value.rs
+++ b/benches/header_value.rs
@@ -1,7 +1,5 @@
 #![feature(test)]
 
-extern crate bytes;
-extern crate http;
 extern crate test;
 
 use bytes::Bytes;
@@ -11,7 +9,6 @@ use test::Bencher;
 static SHORT: &'static [u8] = b"localhost";
 static LONG: &'static [u8] = b"Mozilla/5.0 (X11; CrOS x86_64 9592.71.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.80 Safari/537.36";
 
-
 #[bench]
 fn from_shared_short(b: &mut Bencher) {
     b.bytes = SHORT.len() as u64;
@@ -30,15 +27,12 @@ fn from_shared_long(b: &mut Bencher) {
     });
 }
 
-
 #[bench]
 fn from_shared_unchecked_short(b: &mut Bencher) {
     b.bytes = SHORT.len() as u64;
     let bytes = Bytes::from_static(SHORT);
-    b.iter(|| {
-        unsafe {
-            HeaderValue::from_shared_unchecked(bytes.clone());
-        }
+    b.iter(|| unsafe {
+        HeaderValue::from_shared_unchecked(bytes.clone());
     });
 }
 
@@ -46,9 +40,7 @@ fn from_shared_unchecked_short(b: &mut Bencher) {
 fn from_shared_unchecked_long(b: &mut Bencher) {
     b.bytes = LONG.len() as u64;
     let bytes = Bytes::from_static(LONG);
-    b.iter(|| {
-        unsafe {
-            HeaderValue::from_shared_unchecked(bytes.clone());
-        }
+    b.iter(|| unsafe {
+        HeaderValue::from_shared_unchecked(bytes.clone());
     });
 }
diff --git a/benches/uri.rs b/benches/uri.rs
index bf2e3f48..031c08df 100644
--- a/benches/uri.rs
+++ b/benches/uri.rs
@@ -1,6 +1,5 @@
 #![feature(test)]
 
-extern crate http;
 extern crate test;
 
 use http::Uri;
diff --git a/src/byte_str.rs b/src/byte_str.rs
index 00d9a231..686c661a 100644
--- a/src/byte_str.rs
+++ b/src/byte_str.rs
@@ -10,12 +10,16 @@ pub(crate) struct ByteStr {
 impl ByteStr {
     #[inline]
     pub fn new() -> ByteStr {
-        ByteStr { bytes: Bytes::new() }
+        ByteStr {
+            bytes: Bytes::new(),
+        }
     }
 
     #[inline]
     pub fn from_static(val: &'static str) -> ByteStr {
-        ByteStr { bytes: Bytes::from_static(val.as_bytes()) }
+        ByteStr {
+            bytes: Bytes::from_static(val.as_bytes()),
+        }
     }
 
     #[inline]
@@ -23,7 +27,10 @@ impl ByteStr {
         if cfg!(debug_assertions) {
             match str::from_utf8(&bytes) {
                 Ok(_) => (),
-                Err(err) => panic!("ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}", err, bytes),
+                Err(err) => panic!(
+                    "ByteStr::from_utf8_unchecked() with invalid bytes; error = {}, bytes = {:?}",
+                    err, bytes
+                ),
             }
         }
         ByteStr { bytes: bytes }
@@ -43,14 +50,18 @@ impl ops::Deref for ByteStr {
 impl From<String> for ByteStr {
     #[inline]
     fn from(src: String) -> ByteStr {
-        ByteStr { bytes: Bytes::from(src) }
+        ByteStr {
+            bytes: Bytes::from(src),
+        }
     }
 }
 
 impl<'a> From<&'a str> for ByteStr {
     #[inline]
     fn from(src: &'a str) -> ByteStr {
-        ByteStr { bytes: Bytes::from(src) }
+        ByteStr {
+            bytes: Bytes::copy_from_slice(src.as_bytes()),
+        }
     }
 }
 
diff --git a/src/convert.rs b/src/convert.rs
deleted file mode 100644
index 4d937a6c..00000000
--- a/src/convert.rs
+++ /dev/null
@@ -1,76 +0,0 @@
-use Error;
-use header::{HeaderName, HeaderValue, HeaderMap};
-use method::Method;
-use sealed::Sealed;
-use status::StatusCode;
-use uri::{Scheme, Authority, PathAndQuery, Uri};
-
-/// Private trait for the `http` crate to have generic methods with fallible
-/// conversions.
-///
-/// This trait is similar to the `TryFrom` trait proposed in the standard
-/// library, except this is specialized for the `http` crate and isn't intended
-/// for general consumption.
-///
-/// This trait cannot be implemented types outside of the `http` crate, and is
-/// only intended for use as a generic bound on methods in the `http` crate.
-pub trait HttpTryFrom<T>: Sized + Sealed {
-    /// Associated error with the conversion this implementation represents.
-    type Error: Into<Error>;
-
-    #[doc(hidden)]
-    fn try_from(t: T) -> Result<Self, Self::Error>;
-}
-
-pub(crate) trait HttpTryInto<T>: Sized {
-    fn http_try_into(self) -> Result<T, Error>;
-}
-
-#[doc(hidden)]
-impl<T, U> HttpTryInto<U> for T
-where
-    U: HttpTryFrom<T>,
-    T: Sized,
-{
-    fn http_try_into(self) -> Result<U, Error> {
-        HttpTryFrom::try_from(self)
-            .map_err(|e: U::Error| e.into())
-    }
-}
-
-macro_rules! reflexive {
-    ($($t:ty,)*) => ($(
-        impl HttpTryFrom<$t> for $t {
-            type Error = Error;
-
-            fn try_from(t: Self) -> Result<Self, Self::Error> {
-                Ok(t)
-            }
-        }
-
-        impl Sealed for $t {}
-    )*)
-}
-
-reflexive! {
-    Uri,
-    Method,
-    StatusCode,
-    HeaderName,
-    HeaderValue,
-    Scheme,
-    Authority,
-    PathAndQuery,
-}
-
-// HeaderMap<T> can't use reflexive easily due to the generic T
-
-impl<T> HttpTryFrom<HeaderMap<T>> for HeaderMap<T> {
-    type Error = Error;
-
-    fn try_from(t: Self) -> Result<Self, Self::Error> {
-        Ok(t)
-    }
-}
-
-impl<T> Sealed for HeaderMap<T> {}
diff --git a/src/error.rs b/src/error.rs
index 641c3984..3d06fbc0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -2,10 +2,10 @@ use std::error;
 use std::fmt;
 use std::result;
 
-use header;
-use method;
-use status;
-use uri;
+use crate::header;
+use crate::method;
+use crate::status;
+use crate::uri;
 
 /// A generic "error" for HTTP connections
 ///
@@ -42,7 +42,7 @@ impl fmt::Debug for Error {
 }
 
 impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self.get_ref(), f)
     }
 }
@@ -54,8 +54,7 @@ impl Error {
     }
 
     /// Return a reference to the lower level, inner error.
-    #[allow(warnings)]
-    pub fn get_ref(&self) -> &(error::Error + 'static) {
+    pub fn get_ref(&self) -> &(dyn error::Error + 'static) {
         use self::ErrorKind::*;
 
         match self.inner {
@@ -91,93 +90,86 @@ impl error::Error for Error {
 
     // Return any available cause from the inner error. Note the inner error is
     // not itself the cause.
-    #[allow(warnings)]
-    fn cause(&self) -> Option<&error::Error> {
-        self.get_ref().cause()
+    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+        self.get_ref().source()
     }
 }
 
 impl From<status::InvalidStatusCode> for Error {
     fn from(err: status::InvalidStatusCode) -> Error {
-        Error { inner: ErrorKind::StatusCode(err) }
+        Error {
+            inner: ErrorKind::StatusCode(err),
+        }
     }
 }
 
 impl From<method::InvalidMethod> for Error {
     fn from(err: method::InvalidMethod) -> Error {
-        Error { inner: ErrorKind::Method(err) }
+        Error {
+            inner: ErrorKind::Method(err),
+        }
     }
 }
 
 impl From<uri::InvalidUri> for Error {
     fn from(err: uri::InvalidUri) -> Error {
-        Error { inner: ErrorKind::Uri(err) }
+        Error {
+            inner: ErrorKind::Uri(err),
+        }
     }
 }
 
 impl From<uri::InvalidUriBytes> for Error {
     fn from(err: uri::InvalidUriBytes) -> Error {
-        Error { inner: ErrorKind::UriShared(err) }
+        Error {
+            inner: ErrorKind::UriShared(err),
+        }
     }
 }
 
 impl From<uri::InvalidUriParts> for Error {
     fn from(err: uri::InvalidUriParts) -> Error {
-        Error { inner: ErrorKind::UriParts(err) }
+        Error {
+            inner: ErrorKind::UriParts(err),
+        }
     }
 }
 
 impl From<header::InvalidHeaderName> for Error {
     fn from(err: header::InvalidHeaderName) -> Error {
-        Error { inner: ErrorKind::HeaderName(err) }
+        Error {
+            inner: ErrorKind::HeaderName(err),
+        }
     }
 }
 
 impl From<header::InvalidHeaderNameBytes> for Error {
     fn from(err: header::InvalidHeaderNameBytes) -> Error {
-        Error { inner: ErrorKind::HeaderNameShared(err) }
+        Error {
+            inner: ErrorKind::HeaderNameShared(err),
+        }
     }
 }
 
 impl From<header::InvalidHeaderValue> for Error {
     fn from(err: header::InvalidHeaderValue) -> Error {
-        Error { inner: ErrorKind::HeaderValue(err) }
+        Error {
+            inner: ErrorKind::HeaderValue(err),
+        }
     }
 }
 
 impl From<header::InvalidHeaderValueBytes> for Error {
     fn from(err: header::InvalidHeaderValueBytes) -> Error {
-        Error { inner: ErrorKind::HeaderValueShared(err) }
-    }
-}
-
-// A crate-private type until we can use !.
-//
-// Being crate-private, we should be able to swap the type out in a
-// backwards compatible way.
-pub enum Never {}
-
-impl From<Never> for Error {
-    fn from(never: Never) -> Error {
-        match never {}
-    }
-}
-
-impl fmt::Debug for Never {
-    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {}
-    }
-}
-
-impl fmt::Display for Never {
-    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {}
+        Error {
+            inner: ErrorKind::HeaderValueShared(err),
+        }
     }
 }
 
-impl error::Error for Never {
-    fn description(&self) -> &str {
-        match *self {}
+impl From<std::convert::Infallible> for Error {
+    fn from(err: std::convert::Infallible) -> Error {
+        match err {}
     }
 }
 
@@ -191,11 +183,11 @@ mod tests {
             let err: Error = e.into();
             let ie = err.get_ref();
             assert!(!ie.is::<header::InvalidHeaderValue>());
-            assert!( ie.is::<status::InvalidStatusCode>());
+            assert!(ie.is::<status::InvalidStatusCode>());
             ie.downcast_ref::<status::InvalidStatusCode>().unwrap();
 
             assert!(!err.is::<header::InvalidHeaderValue>());
-            assert!( err.is::<status::InvalidStatusCode>());
+            assert!(err.is::<status::InvalidStatusCode>());
         } else {
             panic!("Bad status allowed!");
         }
diff --git a/src/extensions.rs b/src/extensions.rs
index e8f928fe..e76b953b 100644
--- a/src/extensions.rs
+++ b/src/extensions.rs
@@ -1,11 +1,9 @@
 use std::any::{Any, TypeId};
 use std::collections::HashMap;
-use std::hash::{BuildHasherDefault, Hasher};
 use std::fmt;
+use std::hash::{BuildHasherDefault, Hasher};
 
-// `Box<Any>` is now `Box<dyn Any>`, but we can't change yet (minimum Rust)
-#[allow(warnings)]
-type AnyMap = HashMap<TypeId, Box<Any + Send + Sync>, BuildHasherDefault<IdHasher>>;
+type AnyMap = HashMap<TypeId, Box<dyn Any + Send + Sync>, BuildHasherDefault<IdHasher>>;
 
 // With TypeIds as keys, there's no need to hash them. They are already hashes
 // themselves, coming from the compiler. The IdHasher just holds the u64 of
@@ -29,8 +27,6 @@ impl Hasher for IdHasher {
     }
 }
 
-
-
 /// A type map of protocol extensions.
 ///
 /// `Extensions` can be used by `Request` and `Response` to store
@@ -46,9 +42,7 @@ impl Extensions {
     /// Create an empty `Extensions`.
     #[inline]
     pub fn new() -> Extensions {
-        Extensions {
-            map: None,
-        }
+        Extensions { map: None }
     }
 
     /// Insert a type into this `Extensions`.
@@ -66,18 +60,14 @@ impl Extensions {
     /// assert_eq!(ext.insert(9i32), Some(5i32));
     /// ```
     pub fn insert<T: Send + Sync + 'static>(&mut self, val: T) -> Option<T> {
-        self
-            .map
+        self.map
             .get_or_insert_with(|| Box::new(HashMap::default()))
             .insert(TypeId::of::<T>(), Box::new(val))
             .and_then(|boxed| {
-                #[allow(warnings)]
-                {
-                (boxed as Box<Any + 'static>)
+                (boxed as Box<dyn Any + 'static>)
                     .downcast()
                     .ok()
                     .map(|boxed| *boxed)
-                }
             })
     }
 
@@ -94,16 +84,10 @@ impl Extensions {
     /// assert_eq!(ext.get::<i32>(), Some(&5i32));
     /// ```
     pub fn get<T: Send + Sync + 'static>(&self) -> Option<&T> {
-        self
-            .map
+        self.map
             .as_ref()
             .and_then(|map| map.get(&TypeId::of::<T>()))
-            .and_then(|boxed| {
-                #[allow(warnings)]
-                {
-                (&**boxed as &(Any + 'static)).downcast_ref()
-                }
-            })
+            .and_then(|boxed| (&**boxed as &(dyn Any + 'static)).downcast_ref())
     }
 
     /// Get a mutable reference to a type previously inserted on this `Extensions`.
@@ -119,19 +103,12 @@ impl Extensions {
     /// assert_eq!(ext.get::<String>().unwrap(), "Hello World");
     /// ```
     pub fn get_mut<T: Send + Sync + 'static>(&mut self) -> Option<&mut T> {
-        self
-            .map
+        self.map
             .as_mut()
             .and_then(|map| map.get_mut(&TypeId::of::<T>()))
-            .and_then(|boxed| {
-                #[allow(warnings)]
-                {
-                (&mut **boxed as &mut (Any + 'static)).downcast_mut()
-                }
-            })
+            .and_then(|boxed| (&mut **boxed as &mut (dyn Any + 'static)).downcast_mut())
     }
 
-
     /// Remove a type from this `Extensions`.
     ///
     /// If a extension of this type existed, it will be returned.
@@ -146,18 +123,14 @@ impl Extensions {
     /// assert!(ext.get::<i32>().is_none());
     /// ```
     pub fn remove<T: Send + Sync + 'static>(&mut self) -> Option<T> {
-        self
-            .map
+        self.map
             .as_mut()
             .and_then(|map| map.remove(&TypeId::of::<T>()))
             .and_then(|boxed| {
-                #[allow(warnings)]
-                {
-                (boxed as Box<Any + 'static>)
+                (boxed as Box<dyn Any + 'static>)
                     .downcast()
                     .ok()
                     .map(|boxed| *boxed)
-                }
             })
     }
 
@@ -182,9 +155,8 @@ impl Extensions {
 }
 
 impl fmt::Debug for Extensions {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("Extensions")
-            .finish()
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Extensions").finish()
     }
 }
 
diff --git a/src/header/map.rs b/src/header/map.rs
index 2bb62b55..81dee95c 100644
--- a/src/header/map.rs
+++ b/src/header/map.rs
@@ -1,12 +1,12 @@
-use std::{fmt, mem, ops, ptr, vec};
-use std::collections::hash_map::RandomState;
 use std::collections::HashMap;
+use std::collections::hash_map::RandomState;
+use std::convert::TryFrom;
 use std::hash::{BuildHasher, Hash, Hasher};
-use std::iter::FromIterator;
+use std::iter::{FromIterator, FusedIterator};
 use std::marker::PhantomData;
+use std::{fmt, mem, ops, ptr, vec};
 
-use convert::{HttpTryFrom, HttpTryInto};
-use Error;
+use crate::Error;
 
 use super::HeaderValue;
 use super::name::{HdrName, HeaderName, InvalidHeaderName};
@@ -81,7 +81,7 @@ pub struct HeaderMap<T = HeaderValue> {
 /// Yields `(&HeaderName, &value)` tuples. The same header name may be yielded
 /// more than once if it has more than one associated value.
 #[derive(Debug)]
-pub struct Iter<'a, T: 'a> {
+pub struct Iter<'a, T> {
     inner: IterMut<'a, T>,
 }
 
@@ -90,7 +90,7 @@ pub struct Iter<'a, T: 'a> {
 /// Yields `(&HeaderName, &mut value)` tuples. The same header name may be
 /// yielded more than once if it has more than one associated value.
 #[derive(Debug)]
-pub struct IterMut<'a, T: 'a> {
+pub struct IterMut<'a, T> {
     map: *mut HeaderMap<T>,
     entry: usize,
     cursor: Option<Cursor>,
@@ -113,7 +113,7 @@ pub struct IntoIter<T> {
 /// Each header name is yielded only once, even if it has more than one
 /// associated value.
 #[derive(Debug)]
-pub struct Keys<'a, T: 'a> {
+pub struct Keys<'a, T> {
     inner: ::std::slice::Iter<'a, Bucket<T>>,
 }
 
@@ -121,19 +121,19 @@ pub struct Keys<'a, T: 'a> {
 ///
 /// Each value contained in the `HeaderMap` will be yielded.
 #[derive(Debug)]
-pub struct Values<'a, T: 'a> {
+pub struct Values<'a, T> {
     inner: Iter<'a, T>,
 }
 
 /// `HeaderMap` mutable value iterator
 #[derive(Debug)]
-pub struct ValuesMut<'a, T: 'a> {
+pub struct ValuesMut<'a, T> {
     inner: IterMut<'a, T>,
 }
 
 /// A drain iterator for `HeaderMap`.
 #[derive(Debug)]
-pub struct Drain<'a, T: 'a> {
+pub struct Drain<'a, T> {
     idx: usize,
     len: usize,
     entries: *mut [Bucket<T>],
@@ -145,7 +145,7 @@ pub struct Drain<'a, T: 'a> {
 ///
 /// This struct is returned by `HeaderMap::get_all`.
 #[derive(Debug)]
-pub struct GetAll<'a, T: 'a> {
+pub struct GetAll<'a, T> {
     map: &'a HeaderMap<T>,
     index: Option<usize>,
 }
@@ -164,7 +164,7 @@ pub enum Entry<'a, T: 'a> {
 ///
 /// This struct is returned as part of the `Entry` enum.
 #[derive(Debug)]
-pub struct VacantEntry<'a, T: 'a> {
+pub struct VacantEntry<'a, T> {
     map: &'a mut HeaderMap<T>,
     key: HeaderName,
     hash: HashValue,
@@ -176,7 +176,7 @@ pub struct VacantEntry<'a, T: 'a> {
 ///
 /// This struct is returned as part of the `Entry` enum.
 #[derive(Debug)]
-pub struct OccupiedEntry<'a, T: 'a> {
+pub struct OccupiedEntry<'a, T> {
     map: &'a mut HeaderMap<T>,
     probe: usize,
     index: usize,
@@ -184,7 +184,7 @@ pub struct OccupiedEntry<'a, T: 'a> {
 
 /// An iterator of all values associated with a single header name.
 #[derive(Debug)]
-pub struct ValueIter<'a, T: 'a> {
+pub struct ValueIter<'a, T> {
     map: &'a HeaderMap<T>,
     index: usize,
     front: Option<Cursor>,
@@ -193,7 +193,7 @@ pub struct ValueIter<'a, T: 'a> {
 
 /// A mutable iterator of all values associated with a single header name.
 #[derive(Debug)]
-pub struct ValueIterMut<'a, T: 'a> {
+pub struct ValueIterMut<'a, T> {
     map: *mut HeaderMap<T>,
     index: usize,
     front: Option<Cursor>,
@@ -203,7 +203,7 @@ pub struct ValueIterMut<'a, T: 'a> {
 
 /// An drain iterator of all values associated with a single header name.
 #[derive(Debug)]
-pub struct ValueDrain<'a, T: 'a> {
+pub struct ValueDrain<'a, T> {
     first: Option<T>,
     next: Option<::std::vec::IntoIter<T>>,
     lt: PhantomData<&'a mut HeaderMap<T>>,
@@ -630,7 +630,9 @@ impl<T> HeaderMap<T> {
     pub fn reserve(&mut self, additional: usize) {
         // TODO: This can't overflow if done properly... since the max # of
         // elements is u16::MAX.
-        let cap = self.entries.len()
+        let cap = self
+            .entries
+            .len()
             .checked_add(additional)
             .expect("reserve overflow");
 
@@ -671,13 +673,15 @@ impl<T> HeaderMap<T> {
     /// assert_eq!(map.get("host").unwrap(), &"hello");
     /// ```
     pub fn get<K>(&self, key: K) -> Option<&T>
-        where K: AsHeaderName
+    where
+        K: AsHeaderName,
     {
         self.get2(&key)
     }
 
     fn get2<K>(&self, key: &K) -> Option<&T>
-        where K: AsHeaderName
+    where
+        K: AsHeaderName,
     {
         match key.find(self) {
             Some((_, found)) => {
@@ -706,7 +710,8 @@ impl<T> HeaderMap<T> {
     /// assert_eq!(map.get(HOST).unwrap(), &"hello-world");
     /// ```
     pub fn get_mut<K>(&mut self, key: K) -> Option<&mut T>
-        where K: AsHeaderName
+    where
+        K: AsHeaderName,
     {
         match key.find(self) {
             Some((_, found)) => {
@@ -742,8 +747,9 @@ impl<T> HeaderMap<T> {
     /// assert_eq!(&"goodbye", iter.next().unwrap());
     /// assert!(iter.next().is_none());
     /// ```
-    pub fn get_all<K>(&self, key: K) -> GetAll<T>
-        where K: AsHeaderName
+    pub fn get_all<K>(&self, key: K) -> GetAll<'_, T>
+    where
+        K: AsHeaderName,
     {
         GetAll {
             map: self,
@@ -765,7 +771,8 @@ impl<T> HeaderMap<T> {
     /// assert!(map.contains_key("host"));
     /// ```
     pub fn contains_key<K>(&self, key: K) -> bool
-        where K: AsHeaderName
+    where
+        K: AsHeaderName,
     {
         key.find(self).is_some()
     }
@@ -791,14 +798,14 @@ impl<T> HeaderMap<T> {
     ///     println!("{:?}: {:?}", key, value);
     /// }
     /// ```
-    pub fn iter(&self) -> Iter<T> {
+    pub fn iter(&self) -> Iter<'_, T> {
         Iter {
             inner: IterMut {
                 map: self as *const _ as *mut _,
                 entry: 0,
                 cursor: self.entries.first().map(|_| Cursor::Head),
                 lt: PhantomData,
-            }
+            },
         }
     }
 
@@ -823,7 +830,7 @@ impl<T> HeaderMap<T> {
     ///     value.push_str("-boop");
     /// }
     /// ```
-    pub fn iter_mut(&mut self) -> IterMut<T> {
+    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
         IterMut {
             map: self as *mut _,
             entry: 0,
@@ -853,8 +860,10 @@ impl<T> HeaderMap<T> {
     ///     println!("{:?}", key);
     /// }
     /// ```
-    pub fn keys(&self) -> Keys<T> {
-        Keys { inner: self.entries.iter() }
+    pub fn keys(&self) -> Keys<'_, T> {
+        Keys {
+            inner: self.entries.iter(),
+        }
     }
 
     /// An iterator visiting all values.
@@ -877,7 +886,7 @@ impl<T> HeaderMap<T> {
     ///     println!("{:?}", value);
     /// }
     /// ```
-    pub fn values(&self) -> Values<T> {
+    pub fn values(&self) -> Values<'_, T> {
         Values { inner: self.iter() }
     }
 
@@ -901,8 +910,10 @@ impl<T> HeaderMap<T> {
     ///     value.push_str("-boop");
     /// }
     /// ```
-    pub fn values_mut(&mut self) -> ValuesMut<T> {
-        ValuesMut { inner: self.iter_mut() }
+    pub fn values_mut(&mut self) -> ValuesMut<'_, T> {
+        ValuesMut {
+            inner: self.iter_mut(),
+        }
     }
 
     /// Clears the map, returning all entries as an iterator.
@@ -935,7 +946,7 @@ impl<T> HeaderMap<T> {
     /// assert_eq!("123", vals.next().unwrap());
     /// assert!(vals.next().is_none());
     /// ```
-    pub fn drain(&mut self) -> Drain<T> {
+    pub fn drain(&mut self) -> Drain<'_, T> {
         for i in self.indices.iter_mut() {
             *i = Pos::none();
         }
@@ -961,16 +972,14 @@ impl<T> HeaderMap<T> {
         }
     }
 
-    fn value_iter(&self, idx: Option<usize>) -> ValueIter<T> {
+    fn value_iter(&self, idx: Option<usize>) -> ValueIter<'_, T> {
         use self::Cursor::*;
 
         if let Some(idx) = idx {
             let back = {
                 let entry = &self.entries[idx];
 
-                entry.links
-                    .map(|l| Values(l.tail))
-                    .unwrap_or(Head)
+                entry.links.map(|l| Values(l.tail)).unwrap_or(Head)
             };
 
             ValueIter {
@@ -989,15 +998,13 @@ impl<T> HeaderMap<T> {
         }
     }
 
-    fn value_iter_mut(&mut self, idx: usize) -> ValueIterMut<T> {
+    fn value_iter_mut(&mut self, idx: usize) -> ValueIterMut<'_, T> {
         use self::Cursor::*;
 
         let back = {
             let entry = &self.entries[idx];
 
-            entry.links
-                .map(|l| Values(l.tail))
-                .unwrap_or(Head)
+            entry.links.map(|l| Values(l.tail)).unwrap_or(Head)
         };
 
         ValueIterMut {
@@ -1026,22 +1033,40 @@ impl<T> HeaderMap<T> {
     /// ];
     ///
     /// for &header in headers {
-    ///     let counter = map.entry(header).unwrap().or_insert(0);
+    ///     let counter = map.entry(header).or_insert(0);
     ///     *counter += 1;
     /// }
     ///
     /// assert_eq!(map["content-length"], 2);
     /// assert_eq!(map["x-hello"], 1);
     /// ```
-    pub fn entry<K>(&mut self, key: K) -> Result<Entry<T>, InvalidHeaderName>
-        where K: AsHeaderName,
+    pub fn entry<K>(&mut self, key: K) -> Entry<'_, T>
+    where
+        K: IntoHeaderName,
     {
         key.entry(self)
     }
 
-    fn entry2<K>(&mut self, key: K) -> Entry<T>
-        where K: Hash + Into<HeaderName>,
-              HeaderName: PartialEq<K>,
+    /// Gets the given key's corresponding entry in the map for in-place
+    /// manipulation.
+    ///
+    /// # Errors
+    ///
+    /// This method differs from `entry` by allowing types that may not be
+    /// valid `HeaderName`s to passed as the key (such as `String`). If they
+    /// do not parse as a valid `HeaderName`, this returns an
+    /// `InvalidHeaderName` error.
+    pub fn try_entry<K>(&mut self, key: K) -> Result<Entry<'_, T>, InvalidHeaderName>
+    where
+        K: AsHeaderName,
+    {
+        key.try_entry(self)
+    }
+
+    fn entry2<K>(&mut self, key: K) -> Entry<'_, T>
+    where
+        K: Hash + Into<HeaderName>,
+        HeaderName: PartialEq<K>,
     {
         // Ensure that there is space in the map
         self.reserve_one();
@@ -1071,7 +1096,8 @@ impl<T> HeaderMap<T> {
                 key: key.into(),
                 probe: probe,
                 danger: danger,
-            }))
+            })
+        )
     }
 
     /// Inserts a key-value pair into the map.
@@ -1102,20 +1128,27 @@ impl<T> HeaderMap<T> {
     /// assert_eq!("world", prev);
     /// ```
     pub fn insert<K>(&mut self, key: K, val: T) -> Option<T>
-        where K: IntoHeaderName,
+    where
+        K: IntoHeaderName,
     {
         key.insert(self, val)
     }
 
     #[inline]
     fn insert2<K>(&mut self, key: K, value: T) -> Option<T>
-        where K: Hash + Into<HeaderName>,
-              HeaderName: PartialEq<K>,
+    where
+        K: Hash + Into<HeaderName>,
+        HeaderName: PartialEq<K>,
     {
         self.reserve_one();
 
         insert_phase_one!(
-            self, key, probe, pos, hash, danger,
+            self,
+            key,
+            probe,
+            pos,
+            hash,
+            danger,
             // Vacant
             {
                 drop(danger); // Make lint happy
@@ -1128,14 +1161,10 @@ impl<T> HeaderMap<T> {
             Some(self.insert_occupied(pos, value)),
             // Robinhood
             {
-                self.insert_phase_two(
-                    key.into(),
-                    value,
-                    hash,
-                    probe,
-                    danger);
+                self.insert_phase_two(key.into(), value, hash, probe, danger);
                 None
-            })
+            }
+        )
     }
 
     /// Set an occupied bucket to the given value
@@ -1149,7 +1178,7 @@ impl<T> HeaderMap<T> {
         mem::replace(&mut entry.value, value)
     }
 
-    fn insert_occupied_mult(&mut self, index: usize, value: T) -> ValueDrain<T> {
+    fn insert_occupied_mult(&mut self, index: usize, value: T) -> ValueDrain<'_, T> {
         let old;
         let links;
 
@@ -1202,20 +1231,27 @@ impl<T> HeaderMap<T> {
     /// assert_eq!("earth", *i.next().unwrap());
     /// ```
     pub fn append<K>(&mut self, key: K, value: T) -> bool
-        where K: IntoHeaderName,
+    where
+        K: IntoHeaderName,
     {
         key.append(self, value)
     }
 
     #[inline]
     fn append2<K>(&mut self, key: K, value: T) -> bool
-        where K: Hash + Into<HeaderName>,
-              HeaderName: PartialEq<K>,
+    where
+        K: Hash + Into<HeaderName>,
+        HeaderName: PartialEq<K>,
     {
         self.reserve_one();
 
         insert_phase_one!(
-            self, key, probe, pos, hash, danger,
+            self,
+            key,
+            probe,
+            pos,
+            hash,
+            danger,
             // Vacant
             {
                 drop(danger);
@@ -1231,21 +1267,18 @@ impl<T> HeaderMap<T> {
             },
             // Robinhood
             {
-                self.insert_phase_two(
-                    key.into(),
-                    value,
-                    hash,
-                    probe,
-                    danger);
+                self.insert_phase_two(key.into(), value, hash, probe, danger);
 
                 false
-            })
+            }
+        )
     }
 
     #[inline]
     fn find<K: ?Sized>(&self, key: &K) -> Option<(usize, usize)>
-        where K: Hash + Into<HeaderName>,
-              HeaderName: PartialEq<K>,
+    where
+        K: Hash + Into<HeaderName>,
+        HeaderName: PartialEq<K>,
     {
         if self.entries.is_empty() {
             return None;
@@ -1274,21 +1307,19 @@ impl<T> HeaderMap<T> {
 
     /// phase 2 is post-insert where we forward-shift `Pos` in the indices.
     #[inline]
-    fn insert_phase_two(&mut self,
-                        key: HeaderName,
-                        value: T,
-                        hash: HashValue,
-                        probe: usize,
-                        danger: bool) -> usize
-    {
+    fn insert_phase_two(
+        &mut self,
+        key: HeaderName,
+        value: T,
+        hash: HashValue,
+        probe: usize,
+        danger: bool,
+    ) -> usize {
         // Push the value and get the index
         let index = self.entries.len();
         self.insert_entry(hash, key, value);
 
-        let num_displaced = do_insert_phase_two(
-            &mut self.indices,
-            probe,
-            Pos::new(index, hash));
+        let num_displaced = do_insert_phase_two(&mut self.indices, probe, Pos::new(index, hash));
 
         if danger || num_displaced >= DISPLACEMENT_THRESHOLD {
             // Increase danger level
@@ -1319,7 +1350,8 @@ impl<T> HeaderMap<T> {
     /// assert!(map.remove(HOST).is_none());
     /// ```
     pub fn remove<K>(&mut self, key: K) -> Option<T>
-        where K: AsHeaderName
+    where
+        K: AsHeaderName,
     {
         match key.find(self) {
             Some((probe, idx)) => {
@@ -1425,8 +1457,7 @@ impl<T> HeaderMap<T> {
 
     fn rebuild(&mut self) {
         // Loop over all entries and re-insert them into the map
-        'outer:
-        for (index, entry) in self.entries.iter_mut().enumerate() {
+        'outer: for (index, entry) in self.entries.iter_mut().enumerate() {
             let hash = hash_elem_using(&self.danger, &entry.key);
             let mut probe = desired_pos(self.mask, hash);
             let mut dist = 0;
@@ -1452,10 +1483,7 @@ impl<T> HeaderMap<T> {
                 dist += 1;
             });
 
-            do_insert_phase_two(
-                &mut self.indices,
-                probe,
-                Pos::new(index, hash));
+            do_insert_phase_two(&mut self.indices, probe, Pos::new(index, hash));
         }
     }
 
@@ -1531,7 +1559,10 @@ impl<T> HeaderMap<T> {
 
         // visit the entries in an order where we can simply reinsert them
         // into self.indices without any bucket stealing.
-        let old_indices = mem::replace(&mut self.indices, vec![Pos::none(); new_raw_cap].into_boxed_slice());
+        let old_indices = mem::replace(
+            &mut self.indices,
+            vec![Pos::none(); new_raw_cap].into_boxed_slice(),
+        );
         self.mask = new_raw_cap.wrapping_sub(1) as Size;
 
         for &pos in &old_indices[first_ideal..] {
@@ -1767,14 +1798,14 @@ impl<T> IntoIterator for HeaderMap<T> {
     }
 }
 
-impl<T> FromIterator<(HeaderName, T)> for HeaderMap<T>
-{
+impl<T> FromIterator<(HeaderName, T)> for HeaderMap<T> {
     fn from_iter<I>(iter: I) -> Self
-        where I: IntoIterator<Item = (HeaderName, T)>
+    where
+        I: IntoIterator<Item = (HeaderName, T)>,
     {
-       let mut map = HeaderMap::default();
-       map.extend(iter);
-       map
+        let mut map = HeaderMap::default();
+        map.extend(iter);
+        map
     }
 }
 
@@ -1784,27 +1815,30 @@ impl<T> FromIterator<(HeaderName, T)> for HeaderMap<T>
 ///
 /// ```
 /// use std::collections::HashMap;
-/// use http::{HttpTryFrom, header::HeaderMap};
+/// use std::convert::TryInto;
+/// use http::HeaderMap;
 ///
 /// let mut map = HashMap::new();
 /// map.insert("X-Custom-Header".to_string(), "my value".to_string());
 ///
-/// let headers: HeaderMap = HttpTryFrom::try_from(&map).expect("valid headers");
+/// let headers: HeaderMap = (&map).try_into().expect("valid headers");
 /// assert_eq!(headers["X-Custom-Header"], "my value");
 /// ```
-impl<'a, K, V, T> HttpTryFrom<&'a HashMap<K, V>> for HeaderMap<T>
+impl<'a, K, V, T> TryFrom<&'a HashMap<K, V>> for HeaderMap<T>
     where
         K: Eq + Hash,
-        HeaderName: HttpTryFrom<&'a K>,
-        T: HttpTryFrom<&'a V>
+        HeaderName: TryFrom<&'a K>,
+        <HeaderName as TryFrom<&'a K>>::Error: Into<crate::Error>,
+        T: TryFrom<&'a V>,
+        T::Error: Into<crate::Error>,
 {
     type Error = Error;
 
     fn try_from(c: &'a HashMap<K, V>) -> Result<Self, Self::Error> {
         c.into_iter()
-            .map(|(k, v)| {
-                let name = k.http_try_into()?;
-                let value = v.http_try_into()?;
+            .map(|(k, v)| -> crate::Result<(HeaderName, T)> {
+                let name = TryFrom::try_from(k).map_err(Into::into)?;
+                let value = TryFrom::try_from(v).map_err(Into::into)?;
                 Ok((name, value))
             })
             .collect()
@@ -1859,8 +1893,7 @@ impl<T> Extend<(Option<HeaderName>, T)> for HeaderMap<T> {
             None => return,
         };
 
-        'outer:
-        loop {
+        'outer: loop {
             let mut entry = match self.entry2(key) {
                 Entry::Occupied(mut e) => {
                     // Replace all previous values while maintaining a handle to
@@ -1868,9 +1901,7 @@ impl<T> Extend<(Option<HeaderName>, T)> for HeaderMap<T> {
                     e.insert(val);
                     e
                 }
-                Entry::Vacant(e) => {
-                    e.insert_entry(val)
-                }
+                Entry::Vacant(e) => e.insert_entry(val),
             };
 
             // As long as `HeaderName` is none, keep inserting the value into
@@ -1894,8 +1925,7 @@ impl<T> Extend<(Option<HeaderName>, T)> for HeaderMap<T> {
     }
 }
 
-impl<T> Extend<(HeaderName, T)> for HeaderMap<T>
-{
+impl<T> Extend<(HeaderName, T)> for HeaderMap<T> {
     fn extend<I: IntoIterator<Item = (HeaderName, T)>>(&mut self, iter: I) {
         // Keys may be already present or show multiple times in the iterator.
         // Reserve the entire hint lower bound if the map is empty.
@@ -1923,16 +1953,15 @@ impl<T: PartialEq> PartialEq for HeaderMap<T> {
             return false;
         }
 
-        self.keys().all(|key| {
-            self.get_all(key) == other.get_all(key)
-        })
+        self.keys()
+            .all(|key| self.get_all(key) == other.get_all(key))
     }
 }
 
 impl<T: Eq> Eq for HeaderMap<T> {}
 
 impl<T: fmt::Debug> fmt::Debug for HeaderMap<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_map().entries(self.iter()).finish()
     }
 }
@@ -1944,7 +1973,8 @@ impl<T> Default for HeaderMap<T> {
 }
 
 impl<'a, K, T> ops::Index<K> for HeaderMap<T>
-    where K: AsHeaderName,
+where
+    K: AsHeaderName,
 {
     type Output = T;
 
@@ -1963,11 +1993,7 @@ impl<'a, K, T> ops::Index<K> for HeaderMap<T>
 ///
 /// returns the number of displaced elements
 #[inline]
-fn do_insert_phase_two(indices: &mut [Pos],
-          mut probe: usize,
-          mut old_pos: Pos)
-    -> usize
-{
+fn do_insert_phase_two(indices: &mut [Pos], mut probe: usize, mut old_pos: Pos) -> usize {
     let mut num_displaced = 0;
 
     probe_loop!(probe < indices.len(), {
@@ -1986,11 +2012,12 @@ fn do_insert_phase_two(indices: &mut [Pos],
 }
 
 #[inline]
-fn append_value<T>(entry_idx: usize,
-                   entry: &mut Bucket<T>,
-                   extra: &mut Vec<ExtraValue<T>>,
-                   value: T)
-{
+fn append_value<T>(
+    entry_idx: usize,
+    entry: &mut Bucket<T>,
+    extra: &mut Vec<ExtraValue<T>>,
+    value: T,
+) {
     match entry.links {
         Some(links) => {
             let idx = extra.len();
@@ -2002,10 +2029,7 @@ fn append_value<T>(entry_idx: usize,
 
             extra[links.tail].next = Link::Extra(idx);
 
-            entry.links = Some(Links {
-                tail: idx,
-                .. links
-            });
+            entry.links = Some(Links { tail: idx, ..links });
         }
         None => {
             let idx = extra.len();
@@ -2029,9 +2053,9 @@ impl<'a, T> Iterator for Iter<'a, T> {
     type Item = (&'a HeaderName, &'a T);
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.inner.next_unsafe().map(|(key, ptr)| {
-            (key, unsafe { &*ptr })
-        })
+        self.inner
+            .next_unsafe()
+            .map(|(key, ptr)| (key, unsafe { &*ptr }))
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -2039,6 +2063,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for Iter<'a, T> {}
+
 unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {}
 unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
 
@@ -2082,9 +2108,8 @@ impl<'a, T> Iterator for IterMut<'a, T> {
     type Item = (&'a HeaderName, &'a mut T);
 
     fn next(&mut self) -> Option<Self::Item> {
-        self.next_unsafe().map(|(key, ptr)| {
-            (key, unsafe { &mut *ptr })
-        })
+        self.next_unsafe()
+            .map(|(key, ptr)| (key, unsafe { &mut *ptr }))
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -2100,6 +2125,8 @@ impl<'a, T> Iterator for IterMut<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for IterMut<'a, T> {}
+
 unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {}
 unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
 
@@ -2118,6 +2145,7 @@ impl<'a, T> Iterator for Keys<'a, T> {
 }
 
 impl<'a, T> ExactSizeIterator for Keys<'a, T> {}
+impl<'a, T> FusedIterator for Keys<'a, T> {}
 
 // ===== impl Values ====
 
@@ -2133,6 +2161,8 @@ impl<'a, T> Iterator for Values<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for Values<'a, T> {}
+
 // ===== impl ValuesMut ====
 
 impl<'a, T> Iterator for ValuesMut<'a, T> {
@@ -2147,6 +2177,8 @@ impl<'a, T> Iterator for ValuesMut<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for ValuesMut<'a, T> {}
+
 // ===== impl Drain =====
 
 impl<'a, T> Iterator for Drain<'a, T> {
@@ -2195,6 +2227,8 @@ impl<'a, T> Iterator for Drain<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for Drain<'a, T> {}
+
 impl<'a, T> Drop for Drain<'a, T> {
     fn drop(&mut self) {
         for _ in self {}
@@ -2226,7 +2260,6 @@ impl<'a, T> Entry<'a, T> {
     ///
     /// for &header in headers {
     ///     let counter = map.entry(header)
-    ///         .expect("valid header names")
     ///         .or_insert(0);
     ///     *counter += 1;
     /// }
@@ -2257,7 +2290,7 @@ impl<'a, T> Entry<'a, T> {
     /// # use http::HeaderMap;
     /// let mut map = HeaderMap::new();
     ///
-    /// let res = map.entry("x-hello").unwrap()
+    /// let res = map.entry("x-hello")
     ///     .or_insert_with(|| "world".parse().unwrap());
     ///
     /// assert_eq!(res, "world");
@@ -2272,7 +2305,6 @@ impl<'a, T> Entry<'a, T> {
     /// map.insert(HOST, "world".parse().unwrap());
     ///
     /// let res = map.entry("host")
-    ///     .expect("host is a valid string")
     ///     .or_insert_with(|| unreachable!());
     ///
     ///
@@ -2295,7 +2327,7 @@ impl<'a, T> Entry<'a, T> {
     /// # use http::HeaderMap;
     /// let mut map = HeaderMap::new();
     ///
-    /// assert_eq!(map.entry("x-hello").unwrap().key(), "x-hello");
+    /// assert_eq!(map.entry("x-hello").key(), "x-hello");
     /// ```
     pub fn key(&self) -> &HeaderName {
         use self::Entry::*;
@@ -2318,7 +2350,7 @@ impl<'a, T> VacantEntry<'a, T> {
     /// # use http::HeaderMap;
     /// let mut map = HeaderMap::new();
     ///
-    /// assert_eq!(map.entry("x-hello").unwrap().key().as_str(), "x-hello");
+    /// assert_eq!(map.entry("x-hello").key().as_str(), "x-hello");
     /// ```
     pub fn key(&self) -> &HeaderName {
         &self.key
@@ -2332,7 +2364,7 @@ impl<'a, T> VacantEntry<'a, T> {
     /// # use http::header::{HeaderMap, Entry};
     /// let mut map = HeaderMap::new();
     ///
-    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
+    /// if let Entry::Vacant(v) = map.entry("x-hello") {
     ///     assert_eq!(v.into_key().as_str(), "x-hello");
     /// }
     /// ```
@@ -2351,7 +2383,7 @@ impl<'a, T> VacantEntry<'a, T> {
     /// # use http::header::{HeaderMap, Entry};
     /// let mut map = HeaderMap::new();
     ///
-    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
+    /// if let Entry::Vacant(v) = map.entry("x-hello") {
     ///     v.insert("world".parse().unwrap());
     /// }
     ///
@@ -2359,12 +2391,9 @@ impl<'a, T> VacantEntry<'a, T> {
     /// ```
     pub fn insert(self, value: T) -> &'a mut T {
         // Ensure that there is space in the map
-        let index = self.map.insert_phase_two(
-            self.key,
-            value.into(),
-            self.hash,
-            self.probe,
-            self.danger);
+        let index =
+            self.map
+                .insert_phase_two(self.key, value.into(), self.hash, self.probe, self.danger);
 
         &mut self.map.entries[index].value
     }
@@ -2380,7 +2409,7 @@ impl<'a, T> VacantEntry<'a, T> {
     /// # use http::header::*;
     /// let mut map = HeaderMap::new();
     ///
-    /// if let Entry::Vacant(v) = map.entry("x-hello").unwrap() {
+    /// if let Entry::Vacant(v) = map.entry("x-hello") {
     ///     let mut e = v.insert_entry("world".parse().unwrap());
     ///     e.insert("world2".parse().unwrap());
     /// }
@@ -2389,12 +2418,9 @@ impl<'a, T> VacantEntry<'a, T> {
     /// ```
     pub fn insert_entry(self, value: T) -> OccupiedEntry<'a, T> {
         // Ensure that there is space in the map
-        let index = self.map.insert_phase_two(
-            self.key,
-            value.into(),
-            self.hash,
-            self.probe,
-            self.danger);
+        let index =
+            self.map
+                .insert_phase_two(self.key, value.into(), self.hash, self.probe, self.danger);
 
         OccupiedEntry {
             map: self.map,
@@ -2404,7 +2430,6 @@ impl<'a, T> VacantEntry<'a, T> {
     }
 }
 
-
 // ===== impl GetAll =====
 
 impl<'a, T: 'a> GetAll<'a, T> {
@@ -2433,7 +2458,8 @@ impl<'a, T: 'a> GetAll<'a, T> {
         GetAll {
             map: self.map,
             index: self.index,
-        }.into_iter()
+        }
+        .into_iter()
     }
 }
 
@@ -2469,7 +2495,6 @@ impl<'a, T: 'a> Iterator for ValueIter<'a, T> {
     fn next(&mut self) -> Option<Self::Item> {
         use self::Cursor::*;
 
-
         match self.front {
             Some(Head) => {
                 let entry = &self.map.entries[self.index];
@@ -2524,7 +2549,6 @@ impl<'a, T: 'a> DoubleEndedIterator for ValueIter<'a, T> {
     fn next_back(&mut self) -> Option<Self::Item> {
         use self::Cursor::*;
 
-
         match self.back {
             Some(Head) => {
                 self.front = None;
@@ -2551,6 +2575,8 @@ impl<'a, T: 'a> DoubleEndedIterator for ValueIter<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for ValueIter<'a, T> {}
+
 // ===== impl ValueIterMut =====
 
 impl<'a, T: 'a> Iterator for ValueIterMut<'a, T> {
@@ -2630,6 +2656,8 @@ impl<'a, T: 'a> DoubleEndedIterator for ValueIterMut<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for ValueIterMut<'a, T> {}
+
 unsafe impl<'a, T: Sync> Sync for ValueIterMut<'a, T> {}
 unsafe impl<'a, T: Send> Send for ValueIterMut<'a, T> {}
 
@@ -2670,13 +2698,17 @@ impl<T> Iterator for IntoIter<T> {
     }
 }
 
+impl<T> FusedIterator for IntoIter<T> {}
+
 impl<T> Drop for IntoIter<T> {
     fn drop(&mut self) {
         // Ensure the iterator is consumed
-        for _ in self.by_ref() { }
+        for _ in self.by_ref() {}
 
         // All the values have already been yielded out.
-        unsafe { self.extra_values.set_len(0); }
+        unsafe {
+            self.extra_values.set_len(0);
+        }
     }
 }
 
@@ -2692,7 +2724,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(e) = map.entry("host") {
     ///     assert_eq!("host", e.key());
     /// }
     /// ```
@@ -2715,7 +2747,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "hello.world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     assert_eq!(e.get(), &"hello.world");
     ///
     ///     e.append("hello.earth".parse().unwrap());
@@ -2742,7 +2774,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::default();
     /// map.insert(HOST, "hello.world".to_string());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     e.get_mut().push_str("-2");
     ///     assert_eq!(e.get(), &"hello.world-2");
     /// }
@@ -2768,7 +2800,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// map.insert(HOST, "hello.world".to_string());
     /// map.append(HOST, "hello.earth".to_string());
     ///
-    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(e) = map.entry("host") {
     ///     e.into_mut().push_str("-2");
     /// }
     ///
@@ -2790,7 +2822,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "hello.world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     let mut prev = e.insert("earth".parse().unwrap());
     ///     assert_eq!("hello.world", prev);
     /// }
@@ -2814,7 +2846,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// map.insert(HOST, "world".parse().unwrap());
     /// map.append(HOST, "world2".parse().unwrap());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     let mut prev = e.insert_mult("earth".parse().unwrap());
     ///     assert_eq!("world", prev.next().unwrap());
     ///     assert_eq!("world2", prev.next().unwrap());
@@ -2823,7 +2855,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     ///
     /// assert_eq!("earth", map["host"]);
     /// ```
-    pub fn insert_mult(&mut self, value: T) -> ValueDrain<T> {
+    pub fn insert_mult(&mut self, value: T) -> ValueDrain<'_, T> {
         self.map.insert_occupied_mult(self.index, value.into())
     }
 
@@ -2839,7 +2871,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     e.append("earth".parse().unwrap());
     /// }
     ///
@@ -2866,7 +2898,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(e) = map.entry("host") {
     ///     let mut prev = e.remove();
     ///     assert_eq!("world", prev);
     /// }
@@ -2890,7 +2922,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// let mut map = HeaderMap::new();
     /// map.insert(HOST, "world".parse().unwrap());
     ///
-    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(e) = map.entry("host") {
     ///     let (key, mut prev) = e.remove_entry();
     ///     assert_eq!("host", key.as_str());
     ///     assert_eq!("world", prev);
@@ -2941,14 +2973,14 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// map.insert(HOST, "world".parse().unwrap());
     /// map.append(HOST, "earth".parse().unwrap());
     ///
-    /// if let Entry::Occupied(e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(e) = map.entry("host") {
     ///     let mut iter = e.iter();
     ///     assert_eq!(&"world", iter.next().unwrap());
     ///     assert_eq!(&"earth", iter.next().unwrap());
     ///     assert!(iter.next().is_none());
     /// }
     /// ```
-    pub fn iter(&self) -> ValueIter<T> {
+    pub fn iter(&self) -> ValueIter<'_, T> {
         self.map.value_iter(Some(self.index))
     }
 
@@ -2965,7 +2997,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// map.insert(HOST, "world".to_string());
     /// map.append(HOST, "earth".to_string());
     ///
-    /// if let Entry::Occupied(mut e) = map.entry("host").unwrap() {
+    /// if let Entry::Occupied(mut e) = map.entry("host") {
     ///     for e in e.iter_mut() {
     ///         e.push_str("-boop");
     ///     }
@@ -2976,7 +3008,7 @@ impl<'a, T> OccupiedEntry<'a, T> {
     /// assert_eq!(&"world-boop", i.next().unwrap());
     /// assert_eq!(&"earth-boop", i.next().unwrap());
     /// ```
-    pub fn iter_mut(&mut self) -> ValueIterMut<T> {
+    pub fn iter_mut(&mut self) -> ValueIterMut<'_, T> {
         self.map.value_iter_mut(self.index)
     }
 }
@@ -3040,10 +3072,11 @@ impl<'a, T> Iterator for ValueDrain<'a, T> {
     }
 }
 
+impl<'a, T> FusedIterator for ValueDrain<'a, T> {}
+
 impl<'a, T> Drop for ValueDrain<'a, T> {
     fn drop(&mut self) {
-        while let Some(_) = self.next() {
-        }
+        while let Some(_) = self.next() {}
     }
 }
 
@@ -3176,7 +3209,8 @@ fn probe_distance(mask: Size, hash: HashValue, current: usize) -> usize {
 }
 
 fn hash_elem_using<K: ?Sized>(danger: &Danger, k: &K) -> HashValue
-    where K: Hash
+where
+    K: Hash,
 {
     use fnv::FnvHasher;
 
@@ -3206,9 +3240,8 @@ fn hash_elem_using<K: ?Sized>(danger: &Danger, k: &K) -> HashValue
  *
  */
 
-
 mod into_header_name {
-    use super::{HdrName, HeaderMap, HeaderName};
+    use super::{Entry, HdrName, HeaderMap, HeaderName};
 
     /// A marker trait used to identify values that can be used as insert keys
     /// to a `HeaderMap`.
@@ -3228,6 +3261,9 @@ mod into_header_name {
 
         #[doc(hidden)]
         fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool;
+
+        #[doc(hidden)]
+        fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<'_, T>;
     }
 
     // ==== impls ====
@@ -3244,6 +3280,12 @@ mod into_header_name {
         fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
             map.append2(self, val)
         }
+
+        #[doc(hidden)]
+        #[inline]
+        fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<'_, T> {
+            map.entry2(self)
+        }
     }
 
     impl IntoHeaderName for HeaderName {}
@@ -3259,6 +3301,12 @@ mod into_header_name {
         fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
             map.append2(self, val)
         }
+
+        #[doc(hidden)]
+        #[inline]
+        fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<'_, T> {
+            map.entry2(self)
+        }
     }
 
     impl<'a> IntoHeaderName for &'a HeaderName {}
@@ -3274,6 +3322,12 @@ mod into_header_name {
         fn append<T>(self, map: &mut HeaderMap<T>, val: T) -> bool {
             HdrName::from_static(self, move |hdr| map.append2(hdr, val))
         }
+
+        #[doc(hidden)]
+        #[inline]
+        fn entry<T>(self, map: &mut HeaderMap<T>) -> Entry<'_, T> {
+            HdrName::from_static(self, move |hdr| map.entry2(hdr))
+        }
     }
 
     impl IntoHeaderName for &'static str {}
@@ -3296,7 +3350,7 @@ mod as_header_name {
     // without breaking any external crate.
     pub trait Sealed {
         #[doc(hidden)]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName>;
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName>;
 
         #[doc(hidden)]
         fn find<T>(&self, map: &HeaderMap<T>) -> Option<(usize, usize)>;
@@ -3310,7 +3364,7 @@ mod as_header_name {
     impl Sealed for HeaderName {
         #[doc(hidden)]
         #[inline]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName> {
             Ok(map.entry2(self))
         }
 
@@ -3331,7 +3385,7 @@ mod as_header_name {
     impl<'a> Sealed for &'a HeaderName {
         #[doc(hidden)]
         #[inline]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName> {
             Ok(map.entry2(self))
         }
 
@@ -3352,7 +3406,7 @@ mod as_header_name {
     impl<'a> Sealed for &'a str {
         #[doc(hidden)]
         #[inline]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName> {
             HdrName::from_bytes(self.as_bytes(), move |hdr| map.entry2(hdr))
         }
 
@@ -3373,8 +3427,8 @@ mod as_header_name {
     impl Sealed for String {
         #[doc(hidden)]
         #[inline]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
-            self.as_str().entry(map)
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName> {
+            self.as_str().try_entry(map)
         }
 
         #[doc(hidden)]
@@ -3394,8 +3448,8 @@ mod as_header_name {
     impl<'a> Sealed for &'a String {
         #[doc(hidden)]
         #[inline]
-        fn entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<T>, InvalidHeaderName> {
-            self.as_str().entry(map)
+        fn try_entry<T>(self, map: &mut HeaderMap<T>) -> Result<Entry<'_, T>, InvalidHeaderName> {
+            self.as_str().try_entry(map)
         }
 
         #[doc(hidden)]
@@ -3413,7 +3467,6 @@ mod as_header_name {
     impl<'a> AsHeaderName for &'a String {}
 }
 
-
 #[test]
 fn test_bounds() {
     fn check_bounds<T: Send + Send>() {}
diff --git a/src/header/mod.rs b/src/header/mod.rs
index 2b858214..dedc95d7 100644
--- a/src/header/mod.rs
+++ b/src/header/mod.rs
@@ -75,35 +75,11 @@ mod name;
 mod value;
 
 pub use self::map::{
-    HeaderMap,
-    AsHeaderName,
-    IntoHeaderName,
-    Iter,
-    IterMut,
-    Keys,
-    Values,
-    ValuesMut,
-    Drain,
-    GetAll,
-    Entry,
-    VacantEntry,
-    OccupiedEntry,
-    ValueIter,
-    ValueIterMut,
-    ValueDrain,
-    IntoIter,
-};
-pub use self::name::{
-    HeaderName,
-    InvalidHeaderName,
-    InvalidHeaderNameBytes,
-};
-pub use self::value::{
-    HeaderValue,
-    InvalidHeaderValue,
-    InvalidHeaderValueBytes,
-    ToStrError,
+    AsHeaderName, Drain, Entry, GetAll, HeaderMap, IntoHeaderName, IntoIter, Iter, IterMut, Keys,
+    OccupiedEntry, VacantEntry, ValueDrain, ValueIter, ValueIterMut, Values, ValuesMut,
 };
+pub use self::name::{HeaderName, InvalidHeaderName, InvalidHeaderNameBytes};
+pub use self::value::{HeaderValue, InvalidHeaderValue, InvalidHeaderValueBytes, ToStrError};
 
 // Use header name constants
 pub use self::name::{
diff --git a/src/header/name.rs b/src/header/name.rs
index df4d2a88..ec2c4434 100644
--- a/src/header/name.rs
+++ b/src/header/name.rs
@@ -1,12 +1,12 @@
-use HttpTryFrom;
-use byte_str::ByteStr;
+use crate::byte_str::ByteStr;
 use bytes::{Bytes, BytesMut};
 
-use std::{fmt, mem};
 use std::borrow::Borrow;
+use std::error::Error;
+use std::convert::{TryFrom};
 use std::hash::{Hash, Hasher};
 use std::str::FromStr;
-use std::error::Error;
+use std::{fmt, mem};
 
 /// Represents an HTTP header field name
 ///
@@ -62,7 +62,7 @@ pub struct InvalidHeaderName {
 
 /// A possible error when converting a `HeaderName` from another type.
 #[derive(Debug)]
-pub struct InvalidHeaderNameBytes(InvalidHeaderName) ;
+pub struct InvalidHeaderNameBytes(InvalidHeaderName);
 
 macro_rules! standard_headers {
     (
@@ -1012,6 +1012,7 @@ const HEADER_CHARS: [u8; 256] = [
         0,     0,     0,     0,     0,     0                              // 25x
 ];
 
+/// Valid header name characters for HTTP/2.0 and HTTP/3.0
 const HEADER_CHARS_H2: [u8; 256] = [
     //  0      1      2      3      4      5      6      7      8      9
         0,     0,     0,     0,     0,     0,     0,     0,     0,     0, //   x
@@ -1062,9 +1063,11 @@ macro_rules! eq {
 /// This version is best under optimized mode, however in a wasm debug compile,
 /// the `eq` macro expands to 1 + 1 + 1 + 1... and wasm explodes when this chain gets too long
 /// See https://github.com/DenisKolodin/yew/issues/478
-fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
-    -> Result<HdrName<'a>, InvalidHeaderName>
-{
+fn parse_hdr<'a>(
+    data: &'a [u8],
+    b: &'a mut [u8; 64],
+    table: &[u8; 256],
+) -> Result<HdrName<'a>, InvalidHeaderName> {
     use self::StandardHeader::*;
 
     let len = data.len();
@@ -1122,9 +1125,7 @@ fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
             super::MAX_HEADER_NAME_LEN);
 
     match len {
-        0 => {
-            Err(InvalidHeaderName::new())
-        }
+        0 => Err(InvalidHeaderName::new()),
         2 => {
             to_lower!(b, data, 2);
 
@@ -1181,18 +1182,18 @@ fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
             to_lower!(b, data, 6);
 
             if eq!(b == b'a' b'c' b'c' b'e' b'p' b't') {
-                return Ok(Accept.into())
+                return Ok(Accept.into());
             } else if eq!(b == b'c' b'o' b'o' b'k' b'i' b'e') {
-                return Ok(Cookie.into())
+                return Ok(Cookie.into());
             } else if eq!(b == b'e' b'x' b'p' b'e' b'c' b't') {
-                return Ok(Expect.into())
+                return Ok(Expect.into());
             } else if eq!(b == b'o' b'r' b'i' b'g' b'i' b'n') {
-                return Ok(Origin.into())
+                return Ok(Origin.into());
             } else if eq!(b == b'p' b'r' b'a' b'g' b'm' b'a') {
-                return Ok(Pragma.into())
+                return Ok(Pragma.into());
             } else if b[0] == b's' {
                 if eq!(b[1] == b'e' b'r' b'v' b'e' b'r') {
-                    return Ok(Server.into())
+                    return Ok(Server.into());
                 }
             }
 
@@ -1224,12 +1225,12 @@ fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
 
             if eq!(b == b'i' b'f' b'-') {
                 if eq!(b[3] == b'm' b'a' b't' b'c' b'h') {
-                    return Ok(IfMatch.into())
+                    return Ok(IfMatch.into());
                 } else if eq!(b[3] == b'r' b'a' b'n' b'g' b'e') {
-                    return Ok(IfRange.into())
+                    return Ok(IfRange.into());
                 }
             } else if eq!(b == b'l' b'o' b'c' b'a' b't' b'i' b'o' b'n') {
-                return Ok(Location.into())
+                return Ok(Location.into());
             }
 
             validate(b, len)
@@ -1281,20 +1282,21 @@ fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
 
             if b[0] == b'a' {
                 if eq!(b[1] == b'c' b'c' b'e' b'p' b't' b'-' b'r' b'a' b'n' b'g' b'e' b's') {
-                    return Ok(AcceptRanges.into())
+                    return Ok(AcceptRanges.into());
                 } else if eq!(b[1] == b'u' b't' b'h' b'o' b'r' b'i' b'z' b'a' b't' b'i' b'o' b'n') {
-                    return Ok(Authorization.into())
+                    return Ok(Authorization.into());
                 }
             } else if b[0] == b'c' {
                 if eq!(b[1] == b'a' b'c' b'h' b'e' b'-' b'c' b'o' b'n' b't' b'r' b'o' b'l') {
-                    return Ok(CacheControl.into())
-                } else if eq!(b[1] == b'o' b'n' b't' b'e' b'n' b't' b'-' b'r' b'a' b'n' b'g' b'e' ) {
-                    return Ok(ContentRange.into())
+                    return Ok(CacheControl.into());
+                } else if eq!(b[1] == b'o' b'n' b't' b'e' b'n' b't' b'-' b'r' b'a' b'n' b'g' b'e' )
+                {
+                    return Ok(ContentRange.into());
                 }
             } else if eq!(b == b'i' b'f' b'-' b'n' b'o' b'n' b'e' b'-' b'm' b'a' b't' b'c' b'h') {
-                return Ok(IfNoneMatch.into())
+                return Ok(IfNoneMatch.into());
             } else if eq!(b == b'l' b'a' b's' b't' b'-' b'm' b'o' b'd' b'i' b'f' b'i' b'e' b'd') {
-                return Ok(LastModified.into())
+                return Ok(LastModified.into());
             }
 
             validate(b, len)
@@ -1304,7 +1306,8 @@ fn parse_hdr<'a>(data: &'a [u8], b: &'a mut [u8; 64], table: &[u8; 256])
 
             if eq!(b == b'a' b'c' b'c' b'e' b'p' b't' b'-' b'c' b'h' b'a' b'r' b's' b'e' b't') {
                 Ok(AcceptCharset.into())
-            } else if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b'l' b'e' b'n' b'g' b't' b'h') {
+            } else if eq!(b == b'c' b'o' b'n' b't' b'e' b'n' b't' b'-' b'l' b'e' b'n' b'g' b't' b'h')
+            {
                 Ok(ContentLength.into())
             } else {
                 validate(b, len)
@@ -1658,11 +1661,12 @@ impl HeaderName {
     /// This function normalizes the input.
     #[allow(deprecated)]
     pub fn from_bytes(src: &[u8]) -> Result<HeaderName, InvalidHeaderName> {
+        #[allow(deprecated)]
         let mut buf = unsafe { mem::uninitialized() };
         match parse_hdr(src, &mut buf, &HEADER_CHARS)?.inner {
             Repr::Standard(std) => Ok(std.into()),
             Repr::Custom(MaybeLower { buf, lower: true }) => {
-                let buf = Bytes::from(buf);
+                let buf = Bytes::copy_from_slice(buf);
                 let val = unsafe { ByteStr::from_utf8_unchecked(buf) };
                 Ok(Custom(val).into())
             }
@@ -1677,7 +1681,7 @@ impl HeaderName {
                         return Err(InvalidHeaderName::new());
                     }
 
-                    dst.put(b);
+                    dst.put_u8(b);
                 }
 
                 let val = unsafe { ByteStr::from_utf8_unchecked(dst.freeze()) };
@@ -1690,8 +1694,8 @@ impl HeaderName {
     /// Converts a slice of bytes to an HTTP header name.
     ///
     /// This function expects the input to only contain lowercase characters.
-    /// This is useful when decoding HTTP/2.0 headers. The HTTP/2.0
-    /// specification requires that all headers be represented in lower case.
+    /// This is useful when decoding HTTP/2.0 or HTTP/3.0 headers. Both
+    /// require that all headers be represented in lower case.
     ///
     /// # Examples
     ///
@@ -1707,11 +1711,12 @@ impl HeaderName {
     /// ```
     #[allow(deprecated)]
     pub fn from_lowercase(src: &[u8]) -> Result<HeaderName, InvalidHeaderName> {
+        #[allow(deprecated)]
         let mut buf = unsafe { mem::uninitialized() };
         match parse_hdr(src, &mut buf, &HEADER_CHARS_H2)?.inner {
             Repr::Standard(std) => Ok(std.into()),
             Repr::Custom(MaybeLower { buf, lower: true }) => {
-                let buf = Bytes::from(buf);
+                let buf = Bytes::copy_from_slice(buf);
                 let val = unsafe { ByteStr::from_utf8_unchecked(buf) };
                 Ok(Custom(val).into())
             }
@@ -1722,7 +1727,7 @@ impl HeaderName {
                     }
                 }
 
-                let buf = Bytes::from(buf);
+                let buf = Bytes::copy_from_slice(buf);
                 let val = unsafe { ByteStr::from_utf8_unchecked(buf) };
                 Ok(Custom(val).into())
             }
@@ -1767,6 +1772,7 @@ impl HeaderName {
     #[allow(deprecated)]
     pub fn from_static(src: &'static str) -> HeaderName {
         let bytes = src.as_bytes();
+        #[allow(deprecated)]
         let mut buf = unsafe { mem::uninitialized() };
         match parse_hdr(bytes, &mut buf, &HEADER_CHARS_H2) {
             Ok(hdr_name) => match hdr_name.inner {
@@ -1809,10 +1815,7 @@ impl FromStr for HeaderName {
     type Err = InvalidHeaderName;
 
     fn from_str(s: &str) -> Result<HeaderName, InvalidHeaderName> {
-        HeaderName::from_bytes(s.as_bytes())
-            .map_err(|_| InvalidHeaderName {
-                _priv: (),
-            })
+        HeaderName::from_bytes(s.as_bytes()).map_err(|_| InvalidHeaderName { _priv: () })
     }
 }
 
@@ -1835,13 +1838,13 @@ impl Borrow<str> for HeaderName {
 }
 
 impl fmt::Debug for HeaderName {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(self.as_str(), fmt)
     }
 }
 
 impl fmt::Display for HeaderName {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self.as_str(), fmt)
     }
 }
@@ -1860,12 +1863,13 @@ impl<'a> From<&'a HeaderName> for HeaderName {
 
 #[doc(hidden)]
 impl<T> From<Repr<T>> for Bytes
-where T: Into<Bytes> {
+where
+    T: Into<Bytes>,
+{
     fn from(repr: Repr<T>) -> Bytes {
         match repr {
-            Repr::Standard(header) =>
-                Bytes::from_static(header.as_str().as_bytes()),
-            Repr::Custom(header) => header.into()
+            Repr::Standard(header) => Bytes::from_static(header.as_str().as_bytes()),
+            Repr::Custom(header) => header.into(),
         }
     }
 }
@@ -1884,16 +1888,7 @@ impl From<HeaderName> for Bytes {
     }
 }
 
-impl<'a> HttpTryFrom<&'a HeaderName> for HeaderName {
-    type Error = ::error::Never;
-
-    #[inline]
-    fn try_from(t: &'a HeaderName) -> Result<Self, Self::Error> {
-        Ok(t.clone())
-    }
-}
-
-impl<'a> HttpTryFrom<&'a str> for HeaderName {
+impl<'a> TryFrom<&'a str> for HeaderName {
     type Error = InvalidHeaderName;
     #[inline]
     fn try_from(s: &'a str) -> Result<Self, Self::Error> {
@@ -1901,7 +1896,7 @@ impl<'a> HttpTryFrom<&'a str> for HeaderName {
     }
 }
 
-impl<'a> HttpTryFrom<&'a String> for HeaderName {
+impl<'a> TryFrom<&'a String> for HeaderName {
     type Error = InvalidHeaderName;
     #[inline]
     fn try_from(s: &'a String) -> Result<Self, Self::Error> {
@@ -1909,7 +1904,7 @@ impl<'a> HttpTryFrom<&'a String> for HeaderName {
     }
 }
 
-impl<'a> HttpTryFrom<&'a [u8]> for HeaderName {
+impl<'a> TryFrom<&'a [u8]> for HeaderName {
     type Error = InvalidHeaderName;
     #[inline]
     fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
@@ -1917,7 +1912,7 @@ impl<'a> HttpTryFrom<&'a [u8]> for HeaderName {
     }
 }
 
-impl HttpTryFrom<Bytes> for HeaderName {
+impl TryFrom<Bytes> for HeaderName {
     type Error = InvalidHeaderNameBytes;
     #[inline]
     fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
@@ -1937,7 +1932,9 @@ impl From<StandardHeader> for HeaderName {
 #[doc(hidden)]
 impl From<Custom> for HeaderName {
     fn from(src: Custom) -> HeaderName {
-        HeaderName { inner: Repr::Custom(src) }
+        HeaderName {
+            inner: Repr::Custom(src),
+        }
     }
 }
 
@@ -1948,7 +1945,6 @@ impl<'a> PartialEq<&'a HeaderName> for HeaderName {
     }
 }
 
-
 impl<'a> PartialEq<HeaderName> for &'a HeaderName {
     #[inline]
     fn eq(&self, other: &HeaderName) -> bool {
@@ -1975,7 +1971,6 @@ impl PartialEq<str> for HeaderName {
     }
 }
 
-
 impl PartialEq<HeaderName> for str {
     /// Performs a case-insensitive comparison of the string against the header
     /// name
@@ -2004,7 +1999,6 @@ impl<'a> PartialEq<&'a str> for HeaderName {
     }
 }
 
-
 impl<'a> PartialEq<HeaderName> for &'a str {
     /// Performs a case-insensitive comparison of the string against the header
     /// name
@@ -2023,7 +2017,7 @@ impl fmt::Debug for InvalidHeaderName {
 }
 
 impl fmt::Display for InvalidHeaderName {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.description().fmt(f)
     }
 }
@@ -2035,7 +2029,7 @@ impl Error for InvalidHeaderName {
 }
 
 impl fmt::Display for InvalidHeaderNameBytes {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0.fmt(f)
     }
 }
@@ -2060,8 +2054,9 @@ impl<'a> HdrName<'a> {
 
     #[allow(deprecated)]
     pub fn from_bytes<F, U>(hdr: &[u8], f: F) -> Result<U, InvalidHeaderName>
-        where F: FnOnce(HdrName) -> U,
+        where F: FnOnce(HdrName<'_>) -> U,
     {
+        #[allow(deprecated)]
         let mut buf = unsafe { mem::uninitialized() };
         let hdr = parse_hdr(hdr, &mut buf, &HEADER_CHARS)?;
         Ok(f(hdr))
@@ -2069,11 +2064,13 @@ impl<'a> HdrName<'a> {
 
     #[allow(deprecated)]
     pub fn from_static<F, U>(hdr: &'static str, f: F) -> U
-        where F: FnOnce(HdrName) -> U,
+    where
+        F: FnOnce(HdrName<'_>) -> U,
     {
+        #[allow(deprecated)]
         let mut buf = unsafe { mem::uninitialized() };
-        let hdr = parse_hdr(hdr.as_bytes(), &mut buf, &HEADER_CHARS)
-            .expect("static str is invalid name");
+        let hdr =
+            parse_hdr(hdr.as_bytes(), &mut buf, &HEADER_CHARS).expect("static str is invalid name");
         f(hdr)
     }
 }
@@ -2082,25 +2079,23 @@ impl<'a> HdrName<'a> {
 impl<'a> From<HdrName<'a>> for HeaderName {
     fn from(src: HdrName<'a>) -> HeaderName {
         match src.inner {
-            Repr::Standard(s) => {
-                HeaderName {
-                    inner: Repr::Standard(s),
-                }
-            }
+            Repr::Standard(s) => HeaderName {
+                inner: Repr::Standard(s),
+            },
             Repr::Custom(maybe_lower) => {
                 if maybe_lower.lower {
-                    let buf = Bytes::from(&maybe_lower.buf[..]);
+                    let buf = Bytes::copy_from_slice(&maybe_lower.buf[..]);
                     let byte_str = unsafe { ByteStr::from_utf8_unchecked(buf) };
 
                     HeaderName {
                         inner: Repr::Custom(Custom(byte_str)),
                     }
                 } else {
-                    use bytes::{BufMut};
+                    use bytes::BufMut;
                     let mut dst = BytesMut::with_capacity(maybe_lower.buf.len());
 
                     for b in maybe_lower.buf.iter() {
-                        dst.put(HEADER_CHARS[*b as usize]);
+                        dst.put_u8(HEADER_CHARS[*b as usize]);
                     }
 
                     let buf = unsafe { ByteStr::from_utf8_unchecked(dst.freeze()) };
@@ -2119,24 +2114,20 @@ impl<'a> PartialEq<HdrName<'a>> for HeaderName {
     #[inline]
     fn eq(&self, other: &HdrName<'a>) -> bool {
         match self.inner {
-            Repr::Standard(a) => {
-                match other.inner {
-                    Repr::Standard(b) => a == b,
-                    _ => false,
-                }
-            }
-            Repr::Custom(Custom(ref a)) => {
-                match other.inner {
-                    Repr::Custom(ref b) => {
-                        if b.lower {
-                            a.as_bytes() == b.buf
-                        } else {
-                            eq_ignore_ascii_case(a.as_bytes(), b.buf)
-                        }
+            Repr::Standard(a) => match other.inner {
+                Repr::Standard(b) => a == b,
+                _ => false,
+            },
+            Repr::Custom(Custom(ref a)) => match other.inner {
+                Repr::Custom(ref b) => {
+                    if b.lower {
+                        a.as_bytes() == b.buf
+                    } else {
+                        eq_ignore_ascii_case(a.as_bytes(), b.buf)
                     }
-                    _ => false,
                 }
-            }
+                _ => false,
+            },
         }
     }
 }
diff --git a/src/header/value.rs b/src/header/value.rs
index 25b0078a..7379e468 100644
--- a/src/header/value.rs
+++ b/src/header/value.rs
@@ -1,12 +1,11 @@
 use bytes::{Bytes, BytesMut};
 
-use std::{cmp, fmt, mem, str};
+use std::convert::TryFrom;
 use std::error::Error;
 use std::str::FromStr;
+use std::{cmp, fmt, mem, str};
 
-use ::convert::HttpTryFrom;
-use ::error::Never;
-use header::name::HeaderName;
+use crate::header::name::HeaderName;
 
 /// Represents an HTTP header field value.
 ///
@@ -104,7 +103,7 @@ impl HeaderValue {
     /// ```
     #[inline]
     pub fn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue> {
-        HeaderValue::try_from(src)
+        HeaderValue::try_from_generic(src, |s| Bytes::copy_from_slice(s.as_bytes()))
     }
 
     /// Converts a HeaderName into a HeaderValue
@@ -150,7 +149,7 @@ impl HeaderValue {
     /// ```
     #[inline]
     pub fn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue> {
-        HeaderValue::try_from(src)
+        HeaderValue::try_from_generic(src, Bytes::copy_from_slice)
     }
 
     /// Attempt to convert a `Bytes` buffer to a `HeaderValue`.
@@ -163,7 +162,7 @@ impl HeaderValue {
     /// implementation once the trait is stabilized in std.
     #[inline]
     pub fn from_shared(src: Bytes) -> Result<HeaderValue, InvalidHeaderValueBytes> {
-        HeaderValue::try_from(src).map_err(InvalidHeaderValueBytes)
+        HeaderValue::try_from_generic(src, std::convert::identity).map_err(InvalidHeaderValueBytes)
     }
 
     /// Convert a `Bytes` directly into a `HeaderValue` without validating.
@@ -179,7 +178,7 @@ impl HeaderValue {
                     //TODO: if the Bytes were part of the InvalidHeaderValueBytes,
                     //this message could include the invalid bytes.
                     panic!("HeaderValue::from_shared_unchecked() with invalid bytes");
-                },
+                }
             }
         } else {
             HeaderValue {
@@ -189,16 +188,14 @@ impl HeaderValue {
         }
     }
 
-    fn try_from<T: AsRef<[u8]> + Into<Bytes>>(src: T) -> Result<HeaderValue, InvalidHeaderValue> {
+    fn try_from_generic<T: AsRef<[u8]>, F: FnOnce(T) -> Bytes>(src: T, into: F) -> Result<HeaderValue, InvalidHeaderValue> {
         for &b in src.as_ref() {
             if !is_valid(b) {
-                return Err(InvalidHeaderValue {
-                    _priv: (),
-                });
+                return Err(InvalidHeaderValue { _priv: () });
             }
         }
         Ok(HeaderValue {
-            inner: src.into(),
+            inner: into(src),
             is_sensitive: false,
         })
     }
@@ -329,7 +326,7 @@ impl AsRef<[u8]> for HeaderValue {
 }
 
 impl fmt::Debug for HeaderValue {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if self.is_sensitive {
             f.write_str("Sensitive")
         } else {
@@ -339,9 +336,7 @@ impl fmt::Debug for HeaderValue {
             for (i, &b) in bytes.iter().enumerate() {
                 if !is_visible_ascii(b) || b == b'"' {
                     if from != i {
-                        f.write_str(unsafe {
-                            str::from_utf8_unchecked(&bytes[from..i])
-                        })?;
+                        f.write_str(unsafe { str::from_utf8_unchecked(&bytes[from..i]) })?;
                     }
                     if b == b'"' {
                         f.write_str("\\\"")?;
@@ -352,9 +347,7 @@ impl fmt::Debug for HeaderValue {
                 }
             }
 
-            f.write_str(unsafe {
-                str::from_utf8_unchecked(&bytes[from..])
-            })?;
+            f.write_str(unsafe { str::from_utf8_unchecked(&bytes[from..]) })?;
             f.write_str("\"")
         }
     }
@@ -403,15 +396,6 @@ macro_rules! from_integers {
             }
         }
 
-        impl HttpTryFrom<$t> for HeaderValue {
-            type Error = Never;
-
-            #[inline]
-            fn try_from(num: $t) -> Result<Self, Self::Error> {
-                Ok(num.into())
-            }
-        }
-
         #[test]
         fn $name() {
             let n: $t = 55;
@@ -458,14 +442,17 @@ from_integers! {
 #[cfg(test)]
 mod from_header_name_tests {
     use super::*;
-    use header::map::HeaderMap;
-    use header::name;
+    use crate::header::map::HeaderMap;
+    use crate::header::name;
 
     #[test]
     fn it_can_insert_header_name_as_header_value() {
         let mut map = HeaderMap::new();
         map.insert(name::UPGRADE, name::SEC_WEBSOCKET_PROTOCOL.into());
-        map.insert(name::ACCEPT, name::HeaderName::from_bytes(b"hello-world").unwrap().into());
+        map.insert(
+            name::ACCEPT,
+            name::HeaderName::from_bytes(b"hello-world").unwrap().into(),
+        );
 
         assert_eq!(
             map.get(name::UPGRADE).unwrap(),
@@ -502,16 +489,7 @@ impl<'a> From<&'a HeaderValue> for HeaderValue {
     }
 }
 
-impl<'a> HttpTryFrom<&'a HeaderValue> for HeaderValue {
-    type Error = ::error::Never;
-
-    #[inline]
-    fn try_from(t: &'a HeaderValue) -> Result<Self, Self::Error> {
-        Ok(t.clone())
-    }
-}
-
-impl<'a> HttpTryFrom<&'a str> for HeaderValue {
+impl<'a> TryFrom<&'a str> for HeaderValue {
     type Error = InvalidHeaderValue;
 
     #[inline]
@@ -520,7 +498,7 @@ impl<'a> HttpTryFrom<&'a str> for HeaderValue {
     }
 }
 
-impl<'a> HttpTryFrom<&'a String> for HeaderValue {
+impl<'a> TryFrom<&'a String> for HeaderValue {
     type Error = InvalidHeaderValue;
     #[inline]
     fn try_from(s: &'a String) -> Result<Self, Self::Error> {
@@ -528,7 +506,7 @@ impl<'a> HttpTryFrom<&'a String> for HeaderValue {
     }
 }
 
-impl<'a> HttpTryFrom<&'a [u8]> for HeaderValue {
+impl<'a> TryFrom<&'a [u8]> for HeaderValue {
     type Error = InvalidHeaderValue;
 
     #[inline]
@@ -537,7 +515,7 @@ impl<'a> HttpTryFrom<&'a [u8]> for HeaderValue {
     }
 }
 
-impl HttpTryFrom<String> for HeaderValue {
+impl TryFrom<String> for HeaderValue {
     type Error = InvalidHeaderValueBytes;
 
     #[inline]
@@ -546,29 +524,28 @@ impl HttpTryFrom<String> for HeaderValue {
     }
 }
 
-impl HttpTryFrom<Bytes> for HeaderValue {
+impl TryFrom<Vec<u8>> for HeaderValue {
     type Error = InvalidHeaderValueBytes;
 
     #[inline]
-    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
-        HeaderValue::from_shared(bytes)
+    fn try_from(vec: Vec<u8>) -> Result<Self, Self::Error> {
+        HeaderValue::from_shared(vec.into())
     }
 }
 
-impl HttpTryFrom<HeaderName> for HeaderValue {
-    type Error = InvalidHeaderValue;
+impl TryFrom<Bytes> for HeaderValue {
+    type Error = InvalidHeaderValueBytes;
 
     #[inline]
-    fn try_from(name: HeaderName) -> Result<Self, Self::Error> {
-        // Infallable as header names have the same validations
-        Ok(name.into())
+    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
+        HeaderValue::from_shared(bytes)
     }
 }
 
 #[cfg(test)]
 mod try_from_header_name_tests {
     use super::*;
-    use header::name;
+    use crate::header::name;
 
     #[test]
     fn it_converts_using_try_from() {
@@ -597,7 +574,7 @@ impl fmt::Debug for InvalidHeaderValue {
 }
 
 impl fmt::Display for InvalidHeaderValue {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.description().fmt(f)
     }
 }
@@ -609,7 +586,7 @@ impl Error for InvalidHeaderValue {
 }
 
 impl fmt::Display for InvalidHeaderValueBytes {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0.fmt(f)
     }
 }
@@ -621,7 +598,7 @@ impl Error for InvalidHeaderValueBytes {
 }
 
 impl fmt::Display for ToStrError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.description().fmt(f)
     }
 }
@@ -756,7 +733,8 @@ impl<'a> PartialOrd<HeaderValue> for &'a HeaderValue {
 }
 
 impl<'a, T: ?Sized> PartialEq<&'a T> for HeaderValue
-    where HeaderValue: PartialEq<T>
+where
+    HeaderValue: PartialEq<T>,
 {
     #[inline]
     fn eq(&self, other: &&'a T) -> bool {
@@ -765,7 +743,8 @@ impl<'a, T: ?Sized> PartialEq<&'a T> for HeaderValue
 }
 
 impl<'a, T: ?Sized> PartialOrd<&'a T> for HeaderValue
-    where HeaderValue: PartialOrd<T>
+where
+    HeaderValue: PartialOrd<T>,
 {
     #[inline]
     fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
diff --git a/src/lib.rs b/src/lib.rs
index 874cbbbb..c4d202ee 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -148,10 +148,11 @@
 //!
 //! ```
 //! use http::Uri;
+//! use http::uri::Scheme;
 //!
 //! let uri = "https://www.rust-lang.org/index.html".parse::<Uri>().unwrap();
 //!
-//! assert_eq!(uri.scheme_str(), Some("https"));
+//! assert_eq!(uri.scheme(), Some(&Scheme::HTTPS));
 //! assert_eq!(uri.host(), Some("www.rust-lang.org"));
 //! assert_eq!(uri.path(), "/index.html");
 //! assert_eq!(uri.query(), None);
@@ -159,10 +160,6 @@
 
 #![deny(warnings, missing_docs, missing_debug_implementations)]
 
-extern crate bytes;
-extern crate fnv;
-extern crate itoa;
-
 #[cfg(test)]
 #[macro_use]
 extern crate doc_comment;
@@ -175,25 +172,23 @@ pub mod method;
 pub mod request;
 pub mod response;
 pub mod status;
-pub mod version;
 pub mod uri;
+pub mod version;
 
 mod byte_str;
-mod convert;
 mod error;
 mod extensions;
 
-pub use convert::HttpTryFrom;
-pub use error::{Error, Result};
-pub use extensions::Extensions;
+pub use crate::error::{Error, Result};
+pub use crate::extensions::Extensions;
 #[doc(no_inline)]
-pub use header::{HeaderMap, HeaderValue};
-pub use method::Method;
-pub use request::Request;
-pub use response::Response;
-pub use status::StatusCode;
-pub use uri::Uri;
-pub use version::Version;
+pub use crate::header::{HeaderMap, HeaderValue};
+pub use crate::method::Method;
+pub use crate::request::Request;
+pub use crate::response::Response;
+pub use crate::status::StatusCode;
+pub use crate::uri::Uri;
+pub use crate::version::Version;
 
 fn _assert_types() {
     fn assert_send<T: Send>() {}
diff --git a/src/method.rs b/src/method.rs
index 1631de00..8580a620 100644
--- a/src/method.rs
+++ b/src/method.rs
@@ -15,13 +15,13 @@
 //! assert_eq!(Method::POST.as_str(), "POST");
 //! ```
 
-use HttpTryFrom;
 use self::Inner::*;
 
-use std::{fmt, str};
 use std::convert::AsRef;
 use std::error::Error;
 use std::str::FromStr;
+use std::convert::TryFrom;
+use std::{fmt, str};
 
 /// The Request Method (VERB)
 ///
@@ -110,7 +110,6 @@ const METHOD_CHARS: [u8; 256] = [
     b'\0', b'\0', b'\0', b'\0', b'\0', b'\0'                              // 25x
 ];
 
-
 impl Method {
     /// GET
     pub const GET: Method = Method(Get);
@@ -142,43 +141,31 @@ impl Method {
     /// Converts a slice of bytes to an HTTP method.
     pub fn from_bytes(src: &[u8]) -> Result<Method, InvalidMethod> {
         match src.len() {
-            0 => {
-                Err(InvalidMethod::new())
-            }
-            3 => {
-                match src {
-                    b"GET" => Ok(Method(Get)),
-                    b"PUT" => Ok(Method(Put)),
-                    _ => Method::extension_inline(src),
-                }
-            }
-            4 => {
-                match src {
-                    b"POST" => Ok(Method(Post)),
-                    b"HEAD" => Ok(Method(Head)),
-                    _ => Method::extension_inline(src),
-                }
-            }
-            5 => {
-                match src {
-                    b"PATCH" => Ok(Method(Patch)),
-                    b"TRACE" => Ok(Method(Trace)),
-                    _ => Method::extension_inline(src),
-                }
-            }
-            6 => {
-                match src {
-                    b"DELETE" => Ok(Method(Delete)),
-                    _ => Method::extension_inline(src),
-                }
-            }
-            7 => {
-                match src {
-                    b"OPTIONS" => Ok(Method(Options)),
-                    b"CONNECT" => Ok(Method(Connect)),
-                    _ => Method::extension_inline(src),
-                }
-            }
+            0 => Err(InvalidMethod::new()),
+            3 => match src {
+                b"GET" => Ok(Method(Get)),
+                b"PUT" => Ok(Method(Put)),
+                _ => Method::extension_inline(src),
+            },
+            4 => match src {
+                b"POST" => Ok(Method(Post)),
+                b"HEAD" => Ok(Method(Head)),
+                _ => Method::extension_inline(src),
+            },
+            5 => match src {
+                b"PATCH" => Ok(Method(Patch)),
+                b"TRACE" => Ok(Method(Trace)),
+                _ => Method::extension_inline(src),
+            },
+            6 => match src {
+                b"DELETE" => Ok(Method(Delete)),
+                _ => Method::extension_inline(src),
+            },
+            7 => match src {
+                b"OPTIONS" => Ok(Method(Options)),
+                b"CONNECT" => Ok(Method(Connect)),
+                _ => Method::extension_inline(src),
+            },
             _ => {
                 if src.len() < MAX_INLINE {
                     Method::extension_inline(src)
@@ -209,7 +196,7 @@ impl Method {
     pub fn is_safe(&self) -> bool {
         match self.0 {
             Get | Head | Options | Trace => true,
-            _ => false
+            _ => false,
         }
     }
 
@@ -238,16 +225,10 @@ impl Method {
             Trace => "TRACE",
             Connect => "CONNECT",
             Patch => "PATCH",
-            ExtensionInline(ref data, len) => {
-                unsafe {
-                    str::from_utf8_unchecked(&data[..len as usize])
-                }
-            }
-            ExtensionAllocated(ref data) => {
-                unsafe {
-                    str::from_utf8_unchecked(data)
-                }
-            }
+            ExtensionInline(ref data, len) => unsafe {
+                str::from_utf8_unchecked(&data[..len as usize])
+            },
+            ExtensionAllocated(ref data) => unsafe { str::from_utf8_unchecked(data) },
         }
     }
 }
@@ -275,7 +256,7 @@ impl AsRef<str> for Method {
 
 impl<'a> PartialEq<&'a Method> for Method {
     #[inline]
-    fn eq(&self, other: & &'a Method) -> bool {
+    fn eq(&self, other: &&'a Method) -> bool {
         self == *other
     }
 }
@@ -316,13 +297,13 @@ impl<'a> PartialEq<Method> for &'a str {
 }
 
 impl fmt::Debug for Method {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.as_ref())
     }
 }
 
 impl fmt::Display for Method {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt.write_str(self.as_ref())
     }
 }
@@ -341,16 +322,7 @@ impl<'a> From<&'a Method> for Method {
     }
 }
 
-impl<'a> HttpTryFrom<&'a Method> for Method {
-    type Error = ::error::Never;
-
-    #[inline]
-    fn try_from(t: &'a Method) -> Result<Self, Self::Error> {
-        Ok(t.clone())
-    }
-}
-
-impl<'a> HttpTryFrom<&'a [u8]> for Method {
+impl<'a> TryFrom<&'a [u8]> for Method {
     type Error = InvalidMethod;
 
     #[inline]
@@ -359,12 +331,12 @@ impl<'a> HttpTryFrom<&'a [u8]> for Method {
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for Method {
+impl<'a> TryFrom<&'a str> for Method {
     type Error = InvalidMethod;
 
     #[inline]
     fn try_from(t: &'a str) -> Result<Self, Self::Error> {
-        HttpTryFrom::try_from(t.as_bytes())
+        TryFrom::try_from(t.as_bytes())
     }
 }
 
@@ -373,15 +345,13 @@ impl FromStr for Method {
 
     #[inline]
     fn from_str(t: &str) -> Result<Self, Self::Err> {
-        HttpTryFrom::try_from(t)
+        TryFrom::try_from(t)
     }
 }
 
 impl InvalidMethod {
     fn new() -> InvalidMethod {
-        InvalidMethod {
-            _priv: (),
-        }
+        InvalidMethod { _priv: () }
     }
 }
 
@@ -394,7 +364,7 @@ impl fmt::Debug for InvalidMethod {
 }
 
 impl fmt::Display for InvalidMethod {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.description())
     }
 }
diff --git a/src/request.rs b/src/request.rs
index ac76470e..c249fb96 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -12,12 +12,12 @@
 //! ```no_run
 //! use http::{Request, Response};
 //!
-//! let mut request = Request::builder();
-//! request.uri("https://www.rust-lang.org/")
-//!        .header("User-Agent", "my-awesome-agent/1.0");
+//! let mut request = Request::builder()
+//!     .uri("https://www.rust-lang.org/")
+//!     .header("User-Agent", "my-awesome-agent/1.0");
 //!
 //! if needs_awesome_header() {
-//!     request.header("Awesome", "yes");
+//!     request = request.header("Awesome", "yes");
 //! }
 //!
 //! let response = send(request.body(()).unwrap());
@@ -53,12 +53,13 @@
 //! ```
 
 use std::any::Any;
+use std::convert::{TryFrom};
 use std::fmt;
 
-use {Uri, Error, Result, HttpTryFrom, Extensions};
-use header::{HeaderMap, HeaderName, HeaderValue};
-use method::Method;
-use version::Version;
+use crate::header::{HeaderMap, HeaderName, HeaderValue};
+use crate::method::Method;
+use crate::version::Version;
+use crate::{Extensions, Result, Uri};
 
 /// Represents an HTTP request.
 ///
@@ -74,12 +75,12 @@ use version::Version;
 /// ```no_run
 /// use http::{Request, Response};
 ///
-/// let mut request = Request::builder();
-/// request.uri("https://www.rust-lang.org/")
-///        .header("User-Agent", "my-awesome-agent/1.0");
+/// let mut request = Request::builder()
+///     .uri("https://www.rust-lang.org/")
+///     .header("User-Agent", "my-awesome-agent/1.0");
 ///
 /// if needs_awesome_header() {
-///     request.header("Awesome", "yes");
+///     request = request.header("Awesome", "yes");
 /// }
 ///
 /// let response = send(request.body(()).unwrap());
@@ -187,8 +188,7 @@ pub struct Parts {
 /// through a builder-like pattern.
 #[derive(Debug)]
 pub struct Builder {
-    head: Option<Parts>,
-    err: Option<Error>,
+    inner: Result<Parts>,
 }
 
 impl Request<()> {
@@ -213,7 +213,6 @@ impl Request<()> {
         Builder::new()
     }
 
-
     /// Creates a new `Builder` initialized with a GET method and the given URI.
     ///
     /// This method returns an instance of `Builder` which can be used to
@@ -229,10 +228,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn get<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::GET).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::GET).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a PUT method and the given URI.
@@ -250,10 +251,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn put<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::PUT).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::PUT).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a POST method and the given URI.
@@ -271,10 +274,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn post<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::POST).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::POST).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a DELETE method and the given URI.
@@ -292,10 +297,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn delete<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::DELETE).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::DELETE).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with an OPTIONS method and the given URI.
@@ -314,10 +321,12 @@ impl Request<()> {
     /// # assert_eq!(*request.method(), Method::OPTIONS);
     /// ```
     pub fn options<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::OPTIONS).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::OPTIONS).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a HEAD method and the given URI.
@@ -335,10 +344,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn head<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::HEAD).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::HEAD).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a CONNECT method and the given URI.
@@ -356,10 +367,12 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn connect<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::CONNECT).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+
+    {
+        Builder::new().method(Method::CONNECT).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a PATCH method and the given URI.
@@ -377,10 +390,11 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn patch<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::PATCH).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+    {
+        Builder::new().method(Method::PATCH).uri(uri)
     }
 
     /// Creates a new `Builder` initialized with a TRACE method and the given URI.
@@ -398,10 +412,11 @@ impl Request<()> {
     ///     .unwrap();
     /// ```
     pub fn trace<T>(uri: T) -> Builder
-        where Uri: HttpTryFrom<T> {
-        let mut b = Builder::new();
-        b.method(Method::TRACE).uri(uri);
-        b
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
+    {
+        Builder::new().method(Method::TRACE).uri(uri)
     }
 }
 
@@ -624,7 +639,6 @@ impl<T> Request<T> {
         &mut self.body
     }
 
-
     /// Consumes the request, returning just the body.
     ///
     /// # Examples
@@ -671,9 +685,13 @@ impl<T> Request<T> {
     /// ```
     #[inline]
     pub fn map<F, U>(self, f: F) -> Request<U>
-        where F: FnOnce(T) -> U
+    where
+        F: FnOnce(T) -> U,
     {
-        Request { body: f(self.body), head: self.head }
+        Request {
+            body: f(self.body),
+            head: self.head,
+        }
     }
 }
 
@@ -684,7 +702,7 @@ impl<T: Default> Default for Request<T> {
 }
 
 impl<T: fmt::Debug> fmt::Debug for Request<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Request")
             .field("method", self.method())
             .field("uri", self.uri())
@@ -699,7 +717,7 @@ impl<T: fmt::Debug> fmt::Debug for Request<T> {
 impl Parts {
     /// Creates a new default instance of `Parts`
     fn new() -> Parts {
-        Parts{
+        Parts {
             method: Method::default(),
             uri: Uri::default(),
             version: Version::default(),
@@ -711,7 +729,7 @@ impl Parts {
 }
 
 impl fmt::Debug for Parts {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Parts")
             .field("method", &self.method)
             .field("uri", &self.uri)
@@ -758,44 +776,35 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn method<T>(&mut self, method: T) -> &mut Builder
-        where Method: HttpTryFrom<T>,
+    pub fn method<T>(self, method: T) -> Builder
+    where
+        Method: TryFrom<T>,
+        <Method as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
-            match HttpTryFrom::try_from(method) {
-                Ok(s) => head.method = s,
-                Err(e) => self.err = Some(e.into()),
-            }
-        }
-        self
+        self.and_then(move |mut head| {
+            let method = TryFrom::try_from(method).map_err(Into::into)?;
+            head.method = method;
+            Ok(head)
+        })
     }
 
     /// Get the HTTP Method for this request.
-    /// 
-    /// By default this is `GET`.
-    /// if builder has error, returns None.
-    /// 
+    ///
+    /// By default this is `GET`. If builder has error, returns None.
+    ///
     /// # Examples
-    /// 
+    ///
     /// ```
     /// # use http::*;
-    /// 
+    ///
     /// let mut req = Request::builder();
     /// assert_eq!(req.method_ref(),Some(&Method::GET));
-    /// req.method("POST");
+    ///
+    /// req = req.method("POST");
     /// assert_eq!(req.method_ref(),Some(&Method::POST));
-    /// req.method("DELETE");
-    /// assert_eq!(req.method_ref(),Some(&Method::DELETE));
     /// ```
-    pub fn method_ref(&self) -> Option<&Method>
-    {
-        if self.err.is_some() {
-            return None
-        }
-        match self.head {
-            Some(ref head) => Some(&head.method),
-            None => None
-        }
+    pub fn method_ref(&self) -> Option<&Method> {
+        self.inner.as_ref().ok().map(|h| &h.method)
     }
 
     /// Set the URI for this request.
@@ -815,41 +824,34 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn uri<T>(&mut self, uri: T) -> &mut Builder
-        where Uri: HttpTryFrom<T>,
+    pub fn uri<T>(self, uri: T) -> Builder
+    where
+        Uri: TryFrom<T>,
+        <Uri as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
-            match HttpTryFrom::try_from(uri) {
-                Ok(s) => head.uri = s,
-                Err(e) => self.err = Some(e.into()),
-            }
-        }
-        self
+        self.and_then(move |mut head| {
+            head.uri = TryFrom::try_from(uri).map_err(Into::into)?;
+            Ok(head)
+        })
     }
 
     /// Get the URI for this request
-    /// 
-    /// By default this is `/`
+    ///
+    /// By default this is `/`.
+    ///
     /// # Examples
-    /// 
+    ///
     /// ```
     /// # use http::*;
-    /// 
+    ///
     /// let mut req = Request::builder();
-    /// assert_eq!(req.uri_ref().unwrap().to_string(), "/" );
-    /// req.uri("https://www.rust-lang.org/");
-    /// assert_eq!(req.uri_ref().unwrap().to_string(), "https://www.rust-lang.org/" );
+    /// assert_eq!(req.uri_ref().unwrap(), "/" );
+    ///
+    /// req = req.uri("https://www.rust-lang.org/");
+    /// assert_eq!(req.uri_ref().unwrap(), "https://www.rust-lang.org/" );
     /// ```
-    pub fn uri_ref(&self) -> Option<&Uri>
-    {
-        if self.err.is_some() {
-            return None;
-        }
-        match self.head
-        {
-            Some(ref head) => Some(&head.uri),
-            None => None
-        }
+    pub fn uri_ref(&self) -> Option<&Uri> {
+        self.inner.as_ref().ok().map(|h| &h.uri)
     }
 
     /// Set the HTTP version for this request.
@@ -869,11 +871,11 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn version(&mut self, version: Version) -> &mut Builder {
-        if let Some(head) = head(&mut self.head, &self.err) {
+    pub fn version(self, version: Version) -> Builder {
+        self.and_then(move |mut head| {
             head.version = version;
-        }
-        self
+            Ok(head)
+        })
     }
 
     /// Appends a header to this request builder.
@@ -894,60 +896,47 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Builder
-        where HeaderName: HttpTryFrom<K>,
-              HeaderValue: HttpTryFrom<V>
+    pub fn header<K, V>(self, key: K, value: V) -> Builder
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
+        HeaderValue: TryFrom<V>,
+        <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
-            match <HeaderName as HttpTryFrom<K>>::try_from(key) {
-                Ok(key) => {
-                    match <HeaderValue as HttpTryFrom<V>>::try_from(value) {
-                        Ok(value) => { head.headers.append(key, value); }
-                        Err(e) => self.err = Some(e.into()),
-                    }
-                },
-                Err(e) => self.err = Some(e.into()),
-            };
-        }
-        self
+        self.and_then(move |mut head| {
+            let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
+            let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
+            head.headers.append(name, value);
+            Ok(head)
+        })
     }
 
     /// Get header on this request builder.
     /// when builder has error returns None
-    /// 
+    ///
     /// # Example
-    /// 
+    ///
     /// ```
-    /// # use http::*;
-    /// # use http::header::HeaderValue;
-    /// # use http::request::Builder;
-    /// let mut req = Request::builder();
-    /// req.header("Accept", "text/html")
-    ///    .header("X-Custom-Foo", "bar");
+    /// # use http::Request;
+    /// let req = Request::builder()
+    ///     .header("Accept", "text/html")
+    ///     .header("X-Custom-Foo", "bar");
     /// let headers = req.headers_ref().unwrap();
     /// assert_eq!( headers["Accept"], "text/html" );
     /// assert_eq!( headers["X-Custom-Foo"], "bar" );
     /// ```
     pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
-        if self.err.is_some() {
-            return None;
-        }
-        match self.head
-        {
-            Some(ref head) => Some(&head.headers),
-            None => None
-        }
+        self.inner.as_ref().ok().map(|h| &h.headers)
     }
 
-    /// Get header on this request builder.
-    /// when builder has error returns None
-    /// 
+    /// Get headers on this request builder.
+    ///
+    /// When builder has error returns None.
+    ///
     /// # Example
-    /// 
+    ///
     /// ```
-    /// # use http::*;
-    /// # use http::header::HeaderValue;
-    /// # use http::request::Builder;
+    /// # use http::{header::HeaderValue, Request};
     /// let mut req = Request::builder();
     /// {
     ///   let headers = req.headers_mut().unwrap();
@@ -959,14 +948,7 @@ impl Builder {
     /// assert_eq!( headers["X-Custom-Foo"], "bar" );
     /// ```
     pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
-        if self.err.is_some() {
-            return None;
-        }
-        match self.head
-        {
-            Some(ref mut head) => Some(&mut head.headers),
-            None => None
-        }
+        self.inner.as_mut().ok().map(|h| &mut h.headers)
     }
 
     /// Adds an extension to this builder
@@ -984,21 +966,14 @@ impl Builder {
     /// assert_eq!(req.extensions().get::<&'static str>(),
     ///            Some(&"My Extension"));
     /// ```
-    pub fn extension<T>(&mut self, extension: T) -> &mut Builder
-        where T: Any + Send + Sync + 'static,
+    pub fn extension<T>(self, extension: T) -> Builder
+    where
+        T: Any + Send + Sync + 'static,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
+        self.and_then(move |mut head| {
             head.extensions.insert(extension);
-        }
-        self
-    }
-
-    fn take_parts(&mut self) -> Result<Parts> {
-        let ret = self.head.take().expect("cannot reuse request builder");
-        if let Some(e) = self.err.take() {
-            return Err(e)
-        }
-        Ok(ret)
+            Ok(head)
+        })
     }
 
     /// "Consumes" this builder, using the provided `body` to return a
@@ -1012,11 +987,6 @@ impl Builder {
     /// "Bar\r\n")` the error will be returned when this function is called
     /// rather than when `header` was called.
     ///
-    /// # Panics
-    ///
-    /// This method will panic if the builder is reused. The `body` function can
-    /// only be called once.
-    ///
     /// # Examples
     ///
     /// ```
@@ -1026,29 +996,32 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn body<T>(&mut self, body: T) -> Result<Request<T>> {
-        Ok(Request {
-            head: self.take_parts()?,
-            body: body,
+    pub fn body<T>(self, body: T) -> Result<Request<T>> {
+        self.inner.map(move |head| {
+            Request {
+                head,
+                body,
+            }
         })
     }
-}
 
-fn head<'a>(head: &'a mut Option<Parts>, err: &Option<Error>)
-    -> Option<&'a mut Parts>
-{
-    if err.is_some() {
-        return None
+    // private
+
+    fn and_then<F>(self, func: F) -> Self
+    where
+        F: FnOnce(Parts) -> Result<Parts>
+    {
+        Builder {
+            inner: self.inner.and_then(func),
+        }
     }
-    head.as_mut()
 }
 
 impl Default for Builder {
     #[inline]
     fn default() -> Builder {
         Builder {
-            head: Some(Parts::new()),
-            err: None,
+            inner: Ok(Parts::new()),
         }
     }
 }
@@ -1059,7 +1032,7 @@ mod tests {
 
     #[test]
     fn it_can_map_a_body_from_one_type_to_another() {
-        let request= Request::builder().body("some string").unwrap();
+        let request = Request::builder().body("some string").unwrap();
         let mapped_request = request.map(|s| {
             assert_eq!(s, "some string");
             123u32
diff --git a/src/response.rs b/src/response.rs
index fc877509..7078b812 100644
--- a/src/response.rs
+++ b/src/response.rs
@@ -13,15 +13,15 @@
 //! use http::{Request, Response, StatusCode};
 //!
 //! fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
-//!     let mut response = Response::builder();
-//!     response.header("Foo", "Bar")
-//!             .status(StatusCode::OK);
+//!     let mut builder = Response::builder()
+//!         .header("Foo", "Bar")
+//!         .status(StatusCode::OK);
 //!
 //!     if req.headers().contains_key("Another-Header") {
-//!         response.header("Another-Header", "Ack");
+//!         builder = builder.header("Another-Header", "Ack");
 //!     }
 //!
-//!     response.body(())
+//!     builder.body(())
 //! }
 //! ```
 //!
@@ -62,12 +62,13 @@
 //! ```
 
 use std::any::Any;
+use std::convert::TryFrom;
 use std::fmt;
 
-use {Error, Result, HttpTryFrom, Extensions};
-use header::{HeaderMap, HeaderName, HeaderValue};
-use status::StatusCode;
-use version::Version;
+use crate::header::{HeaderMap, HeaderName, HeaderValue};
+use crate::status::StatusCode;
+use crate::version::Version;
+use crate::{Extensions, Result};
 
 /// Represents an HTTP response
 ///
@@ -77,7 +78,7 @@ use version::Version;
 /// value that has been deserialized.
 ///
 /// Typically you'll work with responses on the client side as the result of
-/// sending a `Request` and on the server you'll be generating a `Request` to
+/// sending a `Request` and on the server you'll be generating a `Response` to
 /// send back to the client.
 ///
 /// # Examples
@@ -88,15 +89,15 @@ use version::Version;
 /// use http::{Request, Response, StatusCode};
 ///
 /// fn respond_to(req: Request<()>) -> http::Result<Response<()>> {
-///     let mut response = Response::builder();
-///     response.header("Foo", "Bar")
-///             .status(StatusCode::OK);
+///     let mut builder = Response::builder()
+///         .header("Foo", "Bar")
+///         .status(StatusCode::OK);
 ///
 ///     if req.headers().contains_key("Another-Header") {
-///         response.header("Another-Header", "Ack");
+///         builder = builder.header("Another-Header", "Ack");
 ///     }
 ///
-///     response.body(())
+///     builder.body(())
 /// }
 /// ```
 ///
@@ -206,8 +207,7 @@ pub struct Parts {
 /// builder-like pattern.
 #[derive(Debug)]
 pub struct Builder {
-    head: Option<Parts>,
-    err: Option<Error>,
+    inner: Result<Parts>,
 }
 
 impl Response<()> {
@@ -471,9 +471,13 @@ impl<T> Response<T> {
     /// ```
     #[inline]
     pub fn map<F, U>(self, f: F) -> Response<U>
-        where F: FnOnce(T) -> U
+    where
+        F: FnOnce(T) -> U,
     {
-        Response { body: f(self.body), head: self.head }
+        Response {
+            body: f(self.body),
+            head: self.head,
+        }
     }
 }
 
@@ -485,7 +489,7 @@ impl<T: Default> Default for Response<T> {
 }
 
 impl<T: fmt::Debug> fmt::Debug for Response<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Response")
             .field("status", &self.status())
             .field("version", &self.version())
@@ -499,7 +503,7 @@ impl<T: fmt::Debug> fmt::Debug for Response<T> {
 impl Parts {
     /// Creates a new default instance of `Parts`
     fn new() -> Parts {
-        Parts{
+        Parts {
             status: StatusCode::default(),
             version: Version::default(),
             headers: HeaderMap::default(),
@@ -510,7 +514,7 @@ impl Parts {
 }
 
 impl fmt::Debug for Parts {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("Parts")
             .field("status", &self.status)
             .field("version", &self.version)
@@ -557,16 +561,15 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn status<T>(&mut self, status: T) -> &mut Builder
-        where StatusCode: HttpTryFrom<T>,
+    pub fn status<T>(self, status: T) -> Builder
+    where
+        StatusCode: TryFrom<T>,
+        <StatusCode as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
-            match HttpTryFrom::try_from(status) {
-                Ok(s) => head.status = s,
-                Err(e) => self.err = Some(e.into()),
-            }
-        }
-        self
+        self.and_then(move |mut head| {
+            head.status = TryFrom::try_from(status).map_err(Into::into)?;
+            Ok(head)
+        })
     }
 
     /// Set the HTTP version for this response.
@@ -586,11 +589,11 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn version(&mut self, version: Version) -> &mut Builder {
-        if let Some(head) = head(&mut self.head, &self.err) {
+    pub fn version(self, version: Version) -> Builder {
+        self.and_then(move |mut head| {
             head.version = version;
-        }
-        self
+            Ok(head)
+        })
     }
 
     /// Appends a header to this response builder.
@@ -612,56 +615,46 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Builder
-        where HeaderName: HttpTryFrom<K>,
-              HeaderValue: HttpTryFrom<V>
+    pub fn header<K, V>(self, key: K, value: V) -> Builder
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<crate::Error>,
+        HeaderValue: TryFrom<V>,
+        <HeaderValue as TryFrom<V>>::Error: Into<crate::Error>,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
-            match <HeaderName as HttpTryFrom<K>>::try_from(key) {
-                Ok(key) => {
-                    match <HeaderValue as HttpTryFrom<V>>::try_from(value) {
-                        Ok(value) => { head.headers.append(key, value); }
-                        Err(e) => self.err = Some(e.into()),
-                    }
-                },
-                Err(e) => self.err = Some(e.into()),
-            };
-        }
-        self
+        self.and_then(move |mut head| {
+            let name = <HeaderName as TryFrom<K>>::try_from(key).map_err(Into::into)?;
+            let value = <HeaderValue as TryFrom<V>>::try_from(value).map_err(Into::into)?;
+            head.headers.append(name, value);
+            Ok(head)
+        })
     }
 
     /// Get header on this response builder.
-    /// when builder has error returns None
-    /// 
+    ///
+    /// When builder has error returns None.
+    ///
     /// # Example
-    /// 
+    ///
     /// ```
-    /// # use http::*;
+    /// # use http::Response;
     /// # use http::header::HeaderValue;
-    /// # use http::response::Builder;
-    /// let mut res = Response::builder();
-    /// res.header("Accept", "text/html")
-    ///    .header("X-Custom-Foo", "bar");
+    /// let res = Response::builder()
+    ///     .header("Accept", "text/html")
+    ///     .header("X-Custom-Foo", "bar");
     /// let headers = res.headers_ref().unwrap();
     /// assert_eq!( headers["Accept"], "text/html" );
     /// assert_eq!( headers["X-Custom-Foo"], "bar" );
     /// ```
     pub fn headers_ref(&self) -> Option<&HeaderMap<HeaderValue>> {
-        if self.err.is_some() {
-            return None;
-        }
-        match self.head
-        {
-            Some(ref head) => Some(&head.headers),
-            None => None
-        }
+        self.inner.as_ref().ok().map(|h| &h.headers)
     }
 
     /// Get header on this response builder.
     /// when builder has error returns None
-    /// 
+    ///
     /// # Example
-    /// 
+    ///
     /// ```
     /// # use http::*;
     /// # use http::header::HeaderValue;
@@ -677,14 +670,7 @@ impl Builder {
     /// assert_eq!( headers["X-Custom-Foo"], "bar" );
     /// ```
     pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>> {
-        if self.err.is_some() {
-            return None;
-        }
-        match self.head
-        {
-            Some(ref mut head) => Some(&mut head.headers),
-            None => None
-        }
+        self.inner.as_mut().ok().map(|h| &mut h.headers)
     }
 
     /// Adds an extension to this builder
@@ -702,21 +688,14 @@ impl Builder {
     /// assert_eq!(response.extensions().get::<&'static str>(),
     ///            Some(&"My Extension"));
     /// ```
-    pub fn extension<T>(&mut self, extension: T) -> &mut Builder
-        where T: Any + Send + Sync + 'static,
+    pub fn extension<T>(self, extension: T) -> Builder
+    where
+        T: Any + Send + Sync + 'static,
     {
-        if let Some(head) = head(&mut self.head, &self.err) {
+        self.and_then(move |mut head| {
             head.extensions.insert(extension);
-        }
-        self
-    }
-
-    fn take_parts(&mut self) -> Result<Parts> {
-        let ret = self.head.take().expect("cannot reuse response builder");
-        if let Some(e) = self.err.take() {
-            return Err(e)
-        }
-        Ok(ret)
+            Ok(head)
+        })
     }
 
     /// "Consumes" this builder, using the provided `body` to return a
@@ -730,11 +709,6 @@ impl Builder {
     /// "Bar\r\n")` the error will be returned when this function is called
     /// rather than when `header` was called.
     ///
-    /// # Panics
-    ///
-    /// This method will panic if the builder is reused. The `body` function can
-    /// only be called once.
-    ///
     /// # Examples
     ///
     /// ```
@@ -744,29 +718,32 @@ impl Builder {
     ///     .body(())
     ///     .unwrap();
     /// ```
-    pub fn body<T>(&mut self, body: T) -> Result<Response<T>> {
-        Ok(Response {
-            head: self.take_parts()?,
-            body: body,
+    pub fn body<T>(self, body: T) -> Result<Response<T>> {
+        self.inner.map(move |head| {
+            Response {
+                head,
+                body,
+            }
         })
     }
-}
 
-fn head<'a>(head: &'a mut Option<Parts>, err: &Option<Error>)
-    -> Option<&'a mut Parts>
-{
-    if err.is_some() {
-        return None
+    // private
+
+    fn and_then<F>(self, func: F) -> Self
+    where
+        F: FnOnce(Parts) -> Result<Parts>
+    {
+        Builder {
+            inner: self.inner.and_then(func),
+        }
     }
-    head.as_mut()
 }
 
 impl Default for Builder {
     #[inline]
     fn default() -> Builder {
         Builder {
-            head: Some(Parts::new()),
-            err: None,
+            inner: Ok(Parts::new()),
         }
     }
 }
diff --git a/src/status.rs b/src/status.rs
index ef95c909..5b4c41f2 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -14,12 +14,11 @@
 //! assert!(StatusCode::OK.is_success());
 //! ```
 
-use std::fmt;
+use std::convert::TryFrom;
 use std::error::Error;
+use std::fmt;
 use std::str::FromStr;
 
-use HttpTryFrom;
-
 /// An HTTP status code (`status-code` in RFC 7230 et al.).
 ///
 /// This type contains constants for all common status codes.
@@ -138,8 +137,9 @@ impl StatusCode {
     /// The reason phrase is defined as being exclusively for human readers. You should avoid
     /// deriving any meaning from it at all costs.
     ///
-    /// Bear in mind also that in HTTP/2.0 the reason phrase is abolished from transmission, and so
-    /// this canonical reason phrase really is the only reason phrase you’ll find.
+    /// Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from
+    /// transmission, and so this canonical reason phrase really is the only reason phrase you’ll
+    /// find.
     ///
     /// # Example
     ///
@@ -151,7 +151,6 @@ impl StatusCode {
         canonical_reason(self.0)
     }
 
-
     /// Check if status is within 100-199.
     #[inline]
     pub fn is_informational(&self) -> bool {
@@ -184,7 +183,7 @@ impl StatusCode {
 }
 
 impl fmt::Debug for StatusCode {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(&self.0, f)
     }
 }
@@ -198,9 +197,13 @@ impl fmt::Debug for StatusCode {
 /// assert_eq!(format!("{}", StatusCode::OK), "200 OK");
 /// ```
 impl fmt::Display for StatusCode {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{} {}", u16::from(*self),
-               self.canonical_reason().unwrap_or("<unknown status code>"))
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(
+            f,
+            "{} {}",
+            u16::from(*self),
+            self.canonical_reason().unwrap_or("<unknown status code>")
+        )
     }
 }
 
@@ -247,16 +250,7 @@ impl<'a> From<&'a StatusCode> for StatusCode {
     }
 }
 
-impl<'a> HttpTryFrom<&'a StatusCode> for StatusCode {
-    type Error = ::error::Never;
-
-    #[inline]
-    fn try_from(t: &'a StatusCode) -> Result<Self, Self::Error> {
-        Ok(t.clone())
-    }
-}
-
-impl<'a> HttpTryFrom<&'a [u8]> for StatusCode {
+impl<'a> TryFrom<&'a [u8]> for StatusCode {
     type Error = InvalidStatusCode;
 
     #[inline]
@@ -265,7 +259,7 @@ impl<'a> HttpTryFrom<&'a [u8]> for StatusCode {
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for StatusCode {
+impl<'a> TryFrom<&'a str> for StatusCode {
     type Error = InvalidStatusCode;
 
     #[inline]
@@ -274,7 +268,7 @@ impl<'a> HttpTryFrom<&'a str> for StatusCode {
     }
 }
 
-impl HttpTryFrom<u16> for StatusCode {
+impl TryFrom<u16> for StatusCode {
     type Error = InvalidStatusCode;
 
     #[inline]
@@ -520,7 +514,7 @@ impl fmt::Debug for InvalidStatusCode {
 }
 
 impl fmt::Display for InvalidStatusCode {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.description())
     }
 }
diff --git a/src/uri/authority.rs b/src/uri/authority.rs
index 0564f2b5..66087b2a 100644
--- a/src/uri/authority.rs
+++ b/src/uri/authority.rs
@@ -1,15 +1,12 @@
-// Deprecated in 1.26, needed until our minimum version is >=1.23.
-#[allow(unused, deprecated)]
-use std::ascii::AsciiExt;
-use std::{cmp, fmt, str};
+use std::convert::TryFrom;
 use std::hash::{Hash, Hasher};
 use std::str::FromStr;
+use std::{cmp, fmt, str};
 
 use bytes::Bytes;
 
-use byte_str::ByteStr;
-use convert::HttpTryFrom;
-use super::{ErrorKind, InvalidUri, InvalidUriBytes, URI_CHARS, Port};
+use super::{ErrorKind, InvalidUri, InvalidUriBytes, Port, URI_CHARS};
+use crate::byte_str::ByteStr;
 
 /// Represents the authority component of a URI.
 #[derive(Clone)]
@@ -19,13 +16,14 @@ pub struct Authority {
 
 impl Authority {
     pub(super) fn empty() -> Self {
-        Authority { data: ByteStr::new() }
+        Authority {
+            data: ByteStr::new(),
+        }
     }
 
     /// Attempt to convert an `Authority` from `Bytes`.
     ///
-    /// This function will be replaced by a `TryFrom` implementation once the
-    /// trait lands in stable.
+    /// This function has been replaced by `TryFrom` implementation.
     ///
     /// # Examples
     ///
@@ -44,15 +42,7 @@ impl Authority {
     /// # }
     /// ```
     pub fn from_shared(s: Bytes) -> Result<Self, InvalidUriBytes> {
-        let authority_end = Authority::parse_non_empty(&s[..]).map_err(InvalidUriBytes)?;
-
-        if authority_end != s.len() {
-            return Err(ErrorKind::InvalidUriChar.into());
-        }
-
-        Ok(Authority {
-            data: unsafe { ByteStr::from_utf8_unchecked(s) },
-        })
+        TryFrom::try_from(s)
     }
 
     /// Attempt to convert an `Authority` from a static string.
@@ -75,7 +65,8 @@ impl Authority {
     pub fn from_static(src: &'static str) -> Self {
         let s = src.as_bytes();
         let b = Bytes::from_static(s);
-        let authority_end = Authority::parse_non_empty(&b[..]).expect("static str is not valid authority");
+        let authority_end =
+            Authority::parse_non_empty(&b[..]).expect("static str is not valid authority");
 
         if authority_end != b.len() {
             panic!("static str is not valid authority");
@@ -205,12 +196,6 @@ impl Authority {
         host(self.as_str())
     }
 
-    #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")]
-    #[doc(hidden)]
-    pub fn port(&self) -> Option<u16> {
-        self.port_u16()
-    }
-
     /// Get the port part of this `Authority`.
     ///
     /// The port subcomponent of authority is designated by an optional port
@@ -233,7 +218,7 @@ impl Authority {
     /// # use http::uri::Authority;
     /// let authority: Authority = "example.org:80".parse().unwrap();
     ///
-    /// let port = authority.port_part().unwrap();
+    /// let port = authority.port().unwrap();
     /// assert_eq!(port.as_u16(), 80);
     /// assert_eq!(port.as_str(), "80");
     /// ```
@@ -244,9 +229,9 @@ impl Authority {
     /// # use http::uri::Authority;
     /// let authority: Authority = "example.org".parse().unwrap();
     ///
-    /// assert!(authority.port_part().is_none());
+    /// assert!(authority.port().is_none());
     /// ```
-    pub fn port_part(&self) -> Option<Port<&str>> {
+    pub fn port(&self) -> Option<Port<&str>> {
         let bytes = self.as_str();
         bytes
             .rfind(":")
@@ -264,7 +249,7 @@ impl Authority {
     /// assert_eq!(authority.port_u16(), Some(80));
     /// ```
     pub fn port_u16(&self) -> Option<u16> {
-        self.port_part().and_then(|p| Some(p.as_u16()))
+        self.port().and_then(|p| Some(p.as_u16()))
     }
 
     /// Return a str representation of the authority
@@ -280,6 +265,40 @@ impl Authority {
     }
 }
 
+impl TryFrom<Bytes> for Authority {
+    type Error = InvalidUriBytes;
+    /// Attempt to convert an `Authority` from `Bytes`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # extern crate http;
+    /// # use http::uri::*;
+    /// extern crate bytes;
+    ///
+    /// use std::convert::TryFrom;
+    /// use bytes::Bytes;
+    ///
+    /// # pub fn main() {
+    /// let bytes = Bytes::from("example.com");
+    /// let authority = Authority::try_from(bytes).unwrap();
+    ///
+    /// assert_eq!(authority.host(), "example.com");
+    /// # }
+    /// ```
+    fn try_from(s: Bytes) -> Result<Self, Self::Error> {
+        let authority_end = Authority::parse_non_empty(&s[..]).map_err(InvalidUriBytes)?;
+
+        if authority_end != s.len() {
+            return Err(ErrorKind::InvalidUriChar.into());
+        }
+
+        Ok(Authority {
+            data: unsafe { ByteStr::from_utf8_unchecked(s) },
+        })
+    }
+}
+
 impl AsRef<str> for Authority {
     fn as_ref(&self) -> &str {
         self.as_str()
@@ -429,7 +448,10 @@ impl PartialOrd<Authority> for String {
 /// assert_eq!(a, b);
 /// ```
 impl Hash for Authority {
-    fn hash<H>(&self, state: &mut H) where H: Hasher {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: Hasher,
+    {
         self.data.len().hash(state);
         for &b in self.data.as_bytes() {
             state.write_u8(b.to_ascii_lowercase());
@@ -437,15 +459,7 @@ impl Hash for Authority {
     }
 }
 
-impl HttpTryFrom<Bytes> for Authority {
-    type Error = InvalidUriBytes;
-    #[inline]
-    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
-        Authority::from_shared(bytes)
-    }
-}
-
-impl<'a> HttpTryFrom<&'a [u8]> for Authority {
+impl<'a> TryFrom<&'a [u8]> for Authority {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
@@ -457,16 +471,18 @@ impl<'a> HttpTryFrom<&'a [u8]> for Authority {
         }
 
         Ok(Authority {
-            data: unsafe { ByteStr::from_utf8_unchecked(s.into()) },
+            data: unsafe {
+                ByteStr::from_utf8_unchecked(Bytes::copy_from_slice(s))
+            },
         })
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for Authority {
+impl<'a> TryFrom<&'a str> for Authority {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a str) -> Result<Self, Self::Error> {
-        HttpTryFrom::try_from(s.as_bytes())
+        TryFrom::try_from(s.as_bytes())
     }
 }
 
@@ -474,7 +490,7 @@ impl FromStr for Authority {
     type Err = InvalidUri;
 
     fn from_str(s: &str) -> Result<Self, InvalidUri> {
-        HttpTryFrom::try_from(s)
+        TryFrom::try_from(s)
     }
 }
 
@@ -486,29 +502,32 @@ impl From<Authority> for Bytes {
 }
 
 impl fmt::Debug for Authority {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.as_str())
     }
 }
 
 impl fmt::Display for Authority {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.as_str())
     }
 }
 
 fn host(auth: &str) -> &str {
-    let host_port = auth.rsplitn(2, '@')
+    let host_port = auth
+        .rsplitn(2, '@')
         .next()
         .expect("split always has at least 1 item");
 
     if host_port.as_bytes()[0] == b'[' {
-        let i = host_port.find(']')
+        let i = host_port
+            .find(']')
             .expect("parsing should validate brackets");
         // ..= ranges aren't available in 1.20, our minimum Rust version...
-        &host_port[0 .. i + 1]
+        &host_port[0..i + 1]
     } else {
-        host_port.split(':')
+        host_port
+            .split(':')
             .next()
             .expect("split always has at least 1 item")
     }
diff --git a/src/uri/builder.rs b/src/uri/builder.rs
index c6d0c93b..56a061a8 100644
--- a/src/uri/builder.rs
+++ b/src/uri/builder.rs
@@ -1,6 +1,7 @@
-use {Uri, Result};
-use convert::{HttpTryFrom, HttpTryInto};
-use super::{Authority, Scheme, Parts, PathAndQuery};
+use std::convert::{TryFrom, TryInto};
+
+use super::{Authority, Parts, PathAndQuery, Scheme};
+use crate::Uri;
 
 /// A builder for `Uri`s.
 ///
@@ -8,7 +9,7 @@ use super::{Authority, Scheme, Parts, PathAndQuery};
 /// through a builder pattern.
 #[derive(Debug)]
 pub struct Builder {
-    parts: Option<Result<Parts>>,
+    parts: Result<Parts, crate::Error>,
 }
 
 impl Builder {
@@ -41,13 +42,15 @@ impl Builder {
     /// let mut builder = uri::Builder::new();
     /// builder.scheme("https");
     /// ```
-    pub fn scheme<T>(&mut self, scheme: T) -> &mut Self
+    pub fn scheme<T>(self, scheme: T) -> Self
     where
-        Scheme: HttpTryFrom<T>,
+        Scheme: TryFrom<T>,
+        <Scheme as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        self.map(|parts| {
-            parts.scheme = Some(scheme.http_try_into()?);
-            Ok(())
+        self.map(move |mut parts| {
+            let scheme = scheme.try_into().map_err(Into::into)?;
+            parts.scheme = Some(scheme);
+            Ok(parts)
         })
     }
 
@@ -63,13 +66,15 @@ impl Builder {
     ///     .build()
     ///     .unwrap();
     /// ```
-    pub fn authority<T>(&mut self, auth: T) -> &mut Self
+    pub fn authority<T>(self, auth: T) -> Self
     where
-        Authority: HttpTryFrom<T>,
+        Authority: TryFrom<T>,
+        <Authority as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        self.map(|parts| {
-            parts.authority = Some(auth.http_try_into()?);
-            Ok(())
+        self.map(move |mut parts| {
+            let auth = auth.try_into().map_err(Into::into)?;
+            parts.authority = Some(auth);
+            Ok(parts)
         })
     }
 
@@ -85,13 +90,15 @@ impl Builder {
     ///     .build()
     ///     .unwrap();
     /// ```
-    pub fn path_and_query<T>(&mut self, p_and_q: T) -> &mut Self
+    pub fn path_and_query<T>(self, p_and_q: T) -> Self
     where
-        PathAndQuery: HttpTryFrom<T>,
+        PathAndQuery: TryFrom<T>,
+        <PathAndQuery as TryFrom<T>>::Error: Into<crate::Error>,
     {
-        self.map(|parts| {
-            parts.path_and_query = Some(p_and_q.http_try_into()?);
-            Ok(())
+        self.map(move |mut parts| {
+            let p_and_q = p_and_q.try_into().map_err(Into::into)?;
+            parts.path_and_query = Some(p_and_q);
+            Ok(parts)
         })
     }
 
@@ -119,29 +126,21 @@ impl Builder {
     ///     .build()
     ///     .unwrap();
     /// ```
-    pub fn build(&mut self) -> Result<Uri> {
-        self
-            .parts
-            .take()
-            .expect("cannot reuse Uri builder")
-            .and_then(|parts| parts.http_try_into())
+    pub fn build(self) -> Result<Uri, crate::Error> {
+        let parts = self.parts?;
+        Uri::from_parts(parts).map_err(Into::into)
     }
 
-    fn map<F>(&mut self, f: F) -> &mut Self
+    // private
+
+    fn map<F>(self, func: F) -> Self
     where
-        F: FnOnce(&mut Parts) -> Result<()>,
+        F: FnOnce(Parts) -> Result<Parts, crate::Error>,
     {
-        let res = if let Some(Ok(ref mut parts)) = self.parts {
-            f(parts)
-        } else {
-            return self;
-        };
 
-        if let Err(err) = res {
-            self.parts = Some(Err(err));
+        Builder {
+            parts: self.parts.and_then(func),
         }
-
-        self
     }
 }
 
@@ -149,8 +148,7 @@ impl Default for Builder {
     #[inline]
     fn default() -> Builder {
         Builder {
-            parts: Some(Ok(Parts::default())),
+            parts: Ok(Parts::default()),
         }
     }
 }
-
diff --git a/src/uri/mod.rs b/src/uri/mod.rs
index 0d2f34b8..0d022c48 100644
--- a/src/uri/mod.rs
+++ b/src/uri/mod.rs
@@ -17,31 +17,28 @@
 //! assert_eq!(uri.host(), None);
 //!
 //! let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
-//! assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https"));
+//! assert_eq!(uri.scheme_str(), Some("https"));
 //! assert_eq!(uri.host(), Some("www.rust-lang.org"));
 //! assert_eq!(uri.path(), "/install.html");
 //! ```
 
-use HttpTryFrom;
-use byte_str::ByteStr;
+use crate::byte_str::ByteStr;
+use std::convert::TryFrom;
 
 use bytes::Bytes;
 
-use std::{fmt, u8, u16};
-// Deprecated in 1.26, needed until our minimum version is >=1.23.
-#[allow(unused, deprecated)]
-use std::ascii::AsciiExt;
+use std::error::Error;
 use std::hash::{Hash, Hasher};
 use std::str::{self, FromStr};
-use std::error::Error;
+use std::{fmt, u16, u8};
 
 use self::scheme::Scheme2;
 
 pub use self::authority::Authority;
 pub use self::builder::Builder;
 pub use self::path::PathAndQuery;
-pub use self::scheme::Scheme;
 pub use self::port::Port;
+pub use self::scheme::Scheme;
 
 mod authority;
 mod builder;
@@ -91,7 +88,7 @@ mod tests;
 /// assert_eq!(uri.host(), None);
 ///
 /// let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
-/// assert_eq!(uri.scheme_part().map(|s| s.as_str()), Some("https"));
+/// assert_eq!(uri.scheme_str(), Some("https"));
 /// assert_eq!(uri.host(), Some("www.rust-lang.org"));
 /// assert_eq!(uri.path(), "/install.html");
 /// ```
@@ -220,7 +217,9 @@ impl Uri {
 
         let scheme = match src.scheme {
             Some(scheme) => scheme,
-            None => Scheme { inner: Scheme2::None },
+            None => Scheme {
+                inner: Scheme2::None,
+            },
         };
 
         let authority = match src.authority {
@@ -242,8 +241,7 @@ impl Uri {
 
     /// Attempt to convert a `Uri` from `Bytes`
     ///
-    /// This function will be replaced by a `TryFrom` implementation once the
-    /// trait lands in stable.
+    /// This function has been replaced by `TryFrom` implementation.
     ///
     /// # Examples
     ///
@@ -263,55 +261,7 @@ impl Uri {
     /// # }
     /// ```
     pub fn from_shared(s: Bytes) -> Result<Uri, InvalidUriBytes> {
-        use self::ErrorKind::*;
-
-        if s.len() > MAX_LEN {
-            return Err(TooLong.into());
-        }
-
-        match s.len() {
-            0 => {
-                return Err(Empty.into());
-            }
-            1 => {
-                match s[0] {
-                    b'/' => {
-                        return Ok(Uri {
-                            scheme: Scheme::empty(),
-                            authority: Authority::empty(),
-                            path_and_query: PathAndQuery::slash(),
-                        });
-                    }
-                    b'*' => {
-                        return Ok(Uri {
-                            scheme: Scheme::empty(),
-                            authority: Authority::empty(),
-                            path_and_query: PathAndQuery::star(),
-                        });
-                    }
-                    _ => {
-                        let authority = Authority::from_shared(s)?;
-
-                        return Ok(Uri {
-                            scheme: Scheme::empty(),
-                            authority: authority,
-                            path_and_query: PathAndQuery::empty(),
-                        });
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        if s[0] == b'/' {
-            return Ok(Uri {
-                scheme: Scheme::empty(),
-                authority: Authority::empty(),
-                path_and_query: PathAndQuery::from_shared(s)?,
-            });
-        }
-
-        parse_full(s)
+        TryFrom::try_from(s)
     }
 
     /// Convert a `Uri` from a static string.
@@ -441,7 +391,7 @@ impl Uri {
     ///
     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
     ///
-    /// assert_eq!(uri.scheme_part(), Some(&Scheme::HTTP));
+    /// assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
     /// ```
     ///
     ///
@@ -451,10 +401,10 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "/hello/world".parse().unwrap();
     ///
-    /// assert!(uri.scheme_part().is_none());
+    /// assert!(uri.scheme().is_none());
     /// ```
     #[inline]
-    pub fn scheme_part(&self) -> Option<&Scheme> {
+    pub fn scheme(&self) -> Option<&Scheme> {
         if self.scheme.inner.is_none() {
             None
         } else {
@@ -462,13 +412,6 @@ impl Uri {
         }
     }
 
-    #[deprecated(since = "0.1.2", note = "use scheme_part or scheme_str instead")]
-    #[doc(hidden)]
-    #[inline]
-    pub fn scheme(&self) -> Option<&str> {
-        self.scheme_str()
-    }
-
     /// Get the scheme of this `Uri` as a `&str`.
     ///
     /// # Example
@@ -515,7 +458,7 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
     ///
-    /// assert_eq!(uri.authority_part().map(|a| a.as_str()), Some("example.org:80"));
+    /// assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
     /// ```
     ///
     ///
@@ -525,10 +468,10 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "/hello/world".parse().unwrap();
     ///
-    /// assert!(uri.authority_part().is_none());
+    /// assert!(uri.authority().is_none());
     /// ```
     #[inline]
-    pub fn authority_part(&self) -> Option<&Authority> {
+    pub fn authority(&self) -> Option<&Authority> {
         if self.authority.data.is_empty() {
             None
         } else {
@@ -536,17 +479,6 @@ impl Uri {
         }
     }
 
-    #[deprecated(since = "0.1.1", note = "use authority_part instead")]
-    #[doc(hidden)]
-    #[inline]
-    pub fn authority(&self) -> Option<&str> {
-        if self.authority.data.is_empty() {
-            None
-        } else {
-            Some(self.authority.as_str())
-        }
-    }
-
     /// Get the host of this `Uri`.
     ///
     /// The host subcomponent of authority is identified by an IP literal
@@ -582,13 +514,7 @@ impl Uri {
     /// ```
     #[inline]
     pub fn host(&self) -> Option<&str> {
-        self.authority_part().map(|a| a.host())
-    }
-
-    #[deprecated(since="0.1.14", note="use `port_part` or `port_u16` instead")]
-    #[doc(hidden)]
-    pub fn port(&self) -> Option<u16> {
-        self.port_u16()
+        self.authority().map(|a| a.host())
     }
 
     /// Get the port part of this `Uri`.
@@ -613,7 +539,7 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
     ///
-    /// let port = uri.port_part().unwrap();
+    /// let port = uri.port().unwrap();
     /// assert_eq!(port.as_u16(), 80);
     /// ```
     ///
@@ -623,7 +549,7 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "http://example.org/hello/world".parse().unwrap();
     ///
-    /// assert!(uri.port_part().is_none());
+    /// assert!(uri.port().is_none());
     /// ```
     ///
     /// Relative URI
@@ -632,11 +558,10 @@ impl Uri {
     /// # use http::Uri;
     /// let uri: Uri = "/hello/world".parse().unwrap();
     ///
-    /// assert!(uri.port_part().is_none());
+    /// assert!(uri.port().is_none());
     /// ```
-    pub fn port_part(&self) -> Option<Port<&str>> {
-        self.authority_part()
-            .and_then(|a| a.port_part())
+    pub fn port(&self) -> Option<Port<&str>> {
+        self.authority().and_then(|a| a.port())
     }
 
     /// Get the port of this `Uri` as a `u16`.
@@ -651,7 +576,7 @@ impl Uri {
     /// assert_eq!(uri.port_u16(), Some(80));
     /// ```
     pub fn port_u16(&self) -> Option<u16> {
-        self.port_part().and_then(|p| Some(p.as_u16()))
+        self.port().and_then(|p| Some(p.as_u16()))
     }
 
     /// Get the query string of this `Uri`, starting after the `?`.
@@ -707,7 +632,81 @@ impl Uri {
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for Uri {
+impl TryFrom<Bytes> for Uri {
+    type Error = InvalidUriBytes;
+
+    /// Attempt to convert a `Uri` from `Bytes`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # extern crate http;
+    /// # use http::uri::*;
+    /// extern crate bytes;
+    ///
+    /// use std::convert::TryFrom;
+    /// use bytes::Bytes;
+    ///
+    /// # pub fn main() {
+    /// let bytes = Bytes::from("http://example.com/foo");
+    /// let uri = Uri::try_from(bytes).unwrap();
+    ///
+    /// assert_eq!(uri.host().unwrap(), "example.com");
+    /// assert_eq!(uri.path(), "/foo");
+    /// # }
+    /// ```
+    fn try_from(s: Bytes) -> Result<Uri, Self::Error> {
+        use self::ErrorKind::*;
+
+        if s.len() > MAX_LEN {
+            return Err(TooLong.into());
+        }
+
+        match s.len() {
+            0 => {
+                return Err(Empty.into());
+            }
+            1 => match s[0] {
+                b'/' => {
+                    return Ok(Uri {
+                        scheme: Scheme::empty(),
+                        authority: Authority::empty(),
+                        path_and_query: PathAndQuery::slash(),
+                    });
+                }
+                b'*' => {
+                    return Ok(Uri {
+                        scheme: Scheme::empty(),
+                        authority: Authority::empty(),
+                        path_and_query: PathAndQuery::star(),
+                    });
+                }
+                _ => {
+                    let authority = Authority::from_shared(s)?;
+
+                    return Ok(Uri {
+                        scheme: Scheme::empty(),
+                        authority: authority,
+                        path_and_query: PathAndQuery::empty(),
+                    });
+                }
+            },
+            _ => {}
+        }
+
+        if s[0] == b'/' {
+            return Ok(Uri {
+                scheme: Scheme::empty(),
+                authority: Authority::empty(),
+                path_and_query: PathAndQuery::from_shared(s)?,
+            });
+        }
+
+        parse_full(s)
+    }
+}
+
+impl<'a> TryFrom<&'a str> for Uri {
     type Error = InvalidUri;
 
     #[inline]
@@ -716,7 +715,7 @@ impl<'a> HttpTryFrom<&'a str> for Uri {
     }
 }
 
-impl<'a> HttpTryFrom<&'a String> for Uri {
+impl<'a> TryFrom<&'a String> for Uri {
     type Error = InvalidUri;
 
     #[inline]
@@ -725,7 +724,7 @@ impl<'a> HttpTryFrom<&'a String> for Uri {
     }
 }
 
-impl HttpTryFrom<String> for Uri {
+impl TryFrom<String> for Uri {
     type Error = InvalidUriBytes;
 
     #[inline]
@@ -734,16 +733,7 @@ impl HttpTryFrom<String> for Uri {
     }
 }
 
-impl HttpTryFrom<Bytes> for Uri {
-    type Error = InvalidUriBytes;
-
-    #[inline]
-    fn try_from(t: Bytes) -> Result<Self, Self::Error> {
-        Uri::from_shared(t)
-    }
-}
-
-impl HttpTryFrom<Parts> for Uri {
+impl TryFrom<Parts> for Uri {
     type Error = InvalidUriParts;
 
     #[inline]
@@ -752,8 +742,8 @@ impl HttpTryFrom<Parts> for Uri {
     }
 }
 
-impl<'a> HttpTryFrom<&'a Uri> for Uri {
-    type Error = ::Error;
+impl<'a> TryFrom<&'a Uri> for Uri {
+    type Error = crate::Error;
 
     #[inline]
     fn try_from(src: &'a Uri) -> Result<Self, Self::Error> {
@@ -776,7 +766,7 @@ impl<'a> HttpTryFrom<&'a Uri> for Uri {
 ///
 /// assert_eq!(uri.path(), "/foo");
 ///
-/// assert!(uri.scheme_part().is_none());
+/// assert!(uri.scheme().is_none());
 /// assert!(uri.authority().is_none());
 /// ```
 ///
@@ -791,7 +781,7 @@ impl<'a> HttpTryFrom<&'a Uri> for Uri {
 ///
 /// let uri = Uri::from_parts(parts).unwrap();
 ///
-/// assert_eq!(uri.scheme_part().unwrap().as_str(), "http");
+/// assert_eq!(uri.scheme().unwrap().as_str(), "http");
 /// assert_eq!(uri.authority().unwrap(), "foo.com");
 /// assert_eq!(uri.path(), "/foo");
 /// ```
@@ -888,17 +878,17 @@ impl FromStr for Uri {
 
     #[inline]
     fn from_str(s: &str) -> Result<Uri, InvalidUri> {
-        Uri::from_shared(s.into()).map_err(|e| e.0)
+        Uri::from_shared(Bytes::copy_from_slice(s.as_bytes())).map_err(|e| e.0)
     }
 }
 
 impl PartialEq for Uri {
     fn eq(&self, other: &Uri) -> bool {
-        if self.scheme_part() != other.scheme_part() {
+        if self.scheme() != other.scheme() {
             return false;
         }
 
-        if self.authority_part() != other.authority_part() {
+        if self.authority() != other.authority() {
             return false;
         }
 
@@ -919,7 +909,7 @@ impl PartialEq<str> for Uri {
         let mut other = other.as_bytes();
         let mut absolute = false;
 
-        if let Some(scheme) = self.scheme_part() {
+        if let Some(scheme) = self.scheme() {
             let scheme = scheme.as_str().as_bytes();
             absolute = true;
 
@@ -940,7 +930,7 @@ impl PartialEq<str> for Uri {
             other = &other[3..];
         }
 
-        if let Some(auth) = self.authority_part() {
+        if let Some(auth) = self.authority() {
             let len = auth.data.len();
             absolute = true;
 
@@ -1000,7 +990,7 @@ impl PartialEq<Uri> for str {
 }
 
 impl<'a> PartialEq<&'a str> for Uri {
-    fn eq(&self, other: & &'a str) -> bool {
+    fn eq(&self, other: &&'a str) -> bool {
         self == *other
     }
 }
@@ -1026,12 +1016,12 @@ impl Default for Uri {
 }
 
 impl fmt::Display for Uri {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        if let Some(scheme) = self.scheme_part() {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if let Some(scheme) = self.scheme() {
             write!(f, "{}://", scheme)?;
         }
 
-        if let Some(authority) = self.authority_part() {
+        if let Some(authority) = self.authority() {
             write!(f, "{}", authority)?;
         }
 
@@ -1046,7 +1036,7 @@ impl fmt::Display for Uri {
 }
 
 impl fmt::Debug for Uri {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self, f)
     }
 }
@@ -1070,7 +1060,7 @@ impl From<ErrorKind> for InvalidUriParts {
 }
 
 impl fmt::Display for InvalidUri {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.description().fmt(f)
     }
 }
@@ -1094,13 +1084,13 @@ impl Error for InvalidUri {
 }
 
 impl fmt::Display for InvalidUriBytes {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0.fmt(f)
     }
 }
 
 impl fmt::Display for InvalidUriParts {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.0.fmt(f)
     }
 }
@@ -1118,13 +1108,16 @@ impl Error for InvalidUriParts {
 }
 
 impl Hash for Uri {
-    fn hash<H>(&self, state: &mut H) where H: Hasher {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: Hasher,
+    {
         if !self.scheme.inner.is_none() {
             self.scheme.hash(state);
             state.write_u8(0xff);
         }
 
-        if let Some(auth) = self.authority_part() {
+        if let Some(auth) = self.authority() {
             auth.hash(state);
         }
 
diff --git a/src/uri/path.rs b/src/uri/path.rs
index 2cafbf89..851db5b7 100644
--- a/src/uri/path.rs
+++ b/src/uri/path.rs
@@ -1,11 +1,11 @@
-use std::{cmp, fmt, str};
+use std::convert::TryFrom;
 use std::str::FromStr;
+use std::{cmp, fmt, str};
 
 use bytes::Bytes;
 
-use byte_str::ByteStr;
-use convert::HttpTryFrom;
 use super::{ErrorKind, InvalidUri, InvalidUriBytes};
+use crate::byte_str::ByteStr;
 
 /// Represents the path component of a URI
 #[derive(Clone)]
@@ -63,16 +63,16 @@ impl PathAndQuery {
                     b'#' => {
                         fragment = Some(i);
                         break;
-                    },
+                    }
 
                     // This is the range of bytes that don't need to be
                     // percent-encoded in the path. If it should have been
                     // percent-encoded, then error.
                     0x21 |
-                    0x24...0x3B |
+                    0x24..=0x3B |
                     0x3D |
-                    0x40...0x5F |
-                    0x61...0x7A |
+                    0x40..=0x5F |
+                    0x61..=0x7A |
                     0x7C |
                     0x7E => {},
 
@@ -94,14 +94,14 @@ impl PathAndQuery {
                         //
                         // Allowed: 0x21 / 0x24 - 0x3B / 0x3D / 0x3F - 0x7E
                         0x21 |
-                        0x24...0x3B |
+                        0x24..=0x3B |
                         0x3D |
-                        0x3F...0x7E => {},
+                        0x3F..=0x7E => {},
 
                         b'#' => {
                             fragment = Some(i);
                             break;
-                        },
+                        }
 
                         _ => return Err(ErrorKind::InvalidUriChar.into()),
                     }
@@ -141,8 +141,7 @@ impl PathAndQuery {
     pub fn from_static(src: &'static str) -> Self {
         let src = Bytes::from_static(src.as_bytes());
 
-        PathAndQuery::from_shared(src)
-            .unwrap()
+        PathAndQuery::from_shared(src).unwrap()
     }
 
     pub(super) fn empty() -> Self {
@@ -284,7 +283,7 @@ impl PathAndQuery {
     }
 }
 
-impl HttpTryFrom<Bytes> for PathAndQuery {
+impl TryFrom<Bytes> for PathAndQuery {
     type Error = InvalidUriBytes;
     #[inline]
     fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
@@ -292,19 +291,19 @@ impl HttpTryFrom<Bytes> for PathAndQuery {
     }
 }
 
-impl<'a> HttpTryFrom<&'a [u8]> for PathAndQuery {
+impl<'a> TryFrom<&'a [u8]> for PathAndQuery {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
-        PathAndQuery::from_shared(s.into()).map_err(|e| e.0)
+        PathAndQuery::from_shared(Bytes::copy_from_slice(s)).map_err(|e| e.0)
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for PathAndQuery {
+impl<'a> TryFrom<&'a str> for PathAndQuery {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a str) -> Result<Self, Self::Error> {
-        HttpTryFrom::try_from(s.as_bytes())
+        TryFrom::try_from(s.as_bytes())
     }
 }
 
@@ -312,7 +311,7 @@ impl FromStr for PathAndQuery {
     type Err = InvalidUri;
     #[inline]
     fn from_str(s: &str) -> Result<Self, InvalidUri> {
-        HttpTryFrom::try_from(s)
+        TryFrom::try_from(s)
     }
 }
 
@@ -323,13 +322,13 @@ impl From<PathAndQuery> for Bytes {
 }
 
 impl fmt::Debug for PathAndQuery {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(self, f)
     }
 }
 
 impl fmt::Display for PathAndQuery {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         if !self.data.is_empty() {
             match self.data.as_bytes()[0] {
                 b'/' | b'*' => write!(fmt, "{}", &self.data[..]),
diff --git a/src/uri/port.rs b/src/uri/port.rs
index d3177a7a..8f5c5f3f 100644
--- a/src/uri/port.rs
+++ b/src/uri/port.rs
@@ -19,7 +19,7 @@ impl<T> Port<T> {
     /// # use http::uri::Authority;
     /// let authority: Authority = "example.org:80".parse().unwrap();
     ///
-    /// let port = authority.port_part().unwrap();
+    /// let port = authority.port().unwrap();
     /// assert_eq!(port.as_u16(), 80);
     /// ```
     pub fn as_u16(&self) -> u16 {
@@ -38,13 +38,8 @@ where
         bytes
             .as_ref()
             .parse::<u16>()
-            .map(|port| Port {
-                port,
-                repr: bytes,
-            })
-            .map_err(|_| {
-                ErrorKind::InvalidPort.into()
-            })
+            .map(|port| Port { port, repr: bytes })
+            .map_err(|_| ErrorKind::InvalidPort.into())
     }
 
     /// Returns the port number as a `str`.
@@ -57,7 +52,7 @@ where
     /// # use http::uri::Authority;
     /// let authority: Authority = "example.org:80".parse().unwrap();
     ///
-    /// let port = authority.port_part().unwrap();
+    /// let port = authority.port().unwrap();
     /// assert_eq!(port.as_str(), "80");
     /// ```
     pub fn as_str(&self) -> &str {
@@ -69,15 +64,13 @@ impl<T> fmt::Debug for Port<T>
 where
     T: fmt::Debug,
 {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("Port")
-            .field(&self.port)
-            .finish()
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("Port").field(&self.port).finish()
     }
 }
 
 impl<T> fmt::Display for Port<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // Use `u16::fmt` so that it respects any formatting flags that
         // may have been set (like padding, align, etc).
         fmt::Display::fmt(&self.port, f)
diff --git a/src/uri/scheme.rs b/src/uri/scheme.rs
index 017cc9a5..f8f32ae0 100644
--- a/src/uri/scheme.rs
+++ b/src/uri/scheme.rs
@@ -1,15 +1,12 @@
-// Deprecated in 1.26, needed until our minimum version is >=1.23.
-#[allow(unused, deprecated)]
-use std::ascii::AsciiExt;
+use std::convert::TryFrom;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::str::FromStr;
 
 use bytes::Bytes;
 
-use byte_str::ByteStr;
-use convert::HttpTryFrom;
 use super::{ErrorKind, InvalidUri, InvalidUriBytes};
+use crate::byte_str::ByteStr;
 
 /// Represents the scheme component of a URI
 #[derive(Clone)]
@@ -43,8 +40,7 @@ impl Scheme {
 
     /// Attempt to convert a `Scheme` from `Bytes`
     ///
-    /// This function will be replaced by a `TryFrom` implementation once the
-    /// trait lands in stable.
+    /// This function has been replaced by `TryFrom` implementation
     ///
     /// # Examples
     ///
@@ -63,16 +59,7 @@ impl Scheme {
     /// # }
     /// ```
     pub fn from_shared(s: Bytes) -> Result<Self, InvalidUriBytes> {
-        use self::Scheme2::*;
-
-        match Scheme2::parse_exact(&s[..]).map_err(InvalidUriBytes)? {
-            None => Err(ErrorKind::InvalidScheme.into()),
-            Standard(p) => Ok(Standard(p).into()),
-            Other(_) => {
-                let b = unsafe { ByteStr::from_utf8_unchecked(s) };
-                Ok(Other(Box::new(b)).into())
-            }
-        }
+        TryFrom::try_from(s)
     }
 
     pub(super) fn empty() -> Self {
@@ -92,8 +79,8 @@ impl Scheme {
     /// ```
     #[inline]
     pub fn as_str(&self) -> &str {
-        use self::Scheme2::*;
         use self::Protocol::*;
+        use self::Scheme2::*;
 
         match self.inner {
             Standard(Http) => "http",
@@ -110,15 +97,43 @@ impl Scheme {
     }
 }
 
-impl HttpTryFrom<Bytes> for Scheme {
+impl TryFrom<Bytes> for Scheme {
     type Error = InvalidUriBytes;
-    #[inline]
-    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
-        Scheme::from_shared(bytes)
+
+    /// Attempt to convert a `Scheme` from `Bytes`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # extern crate http;
+    /// # use http::uri::*;
+    /// extern crate bytes;
+    ///
+    /// use std::convert::TryFrom;
+    /// use bytes::Bytes;
+    ///
+    /// # pub fn main() {
+    /// let bytes = Bytes::from("http");
+    /// let scheme = Scheme::try_from(bytes).unwrap();
+    ///
+    /// assert_eq!(scheme.as_str(), "http");
+    /// # }
+    /// ```
+    fn try_from(s: Bytes) -> Result<Self, Self::Error> {
+        use self::Scheme2::*;
+
+        match Scheme2::parse_exact(&s[..]).map_err(InvalidUriBytes)? {
+            None => Err(ErrorKind::InvalidScheme.into()),
+            Standard(p) => Ok(Standard(p).into()),
+            Other(_) => {
+                let b = unsafe { ByteStr::from_utf8_unchecked(s) };
+                Ok(Other(Box::new(b)).into())
+            }
+        }
     }
 }
 
-impl<'a> HttpTryFrom<&'a [u8]> for Scheme {
+impl<'a> TryFrom<&'a [u8]> for Scheme {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a [u8]) -> Result<Self, Self::Error> {
@@ -130,18 +145,18 @@ impl<'a> HttpTryFrom<&'a [u8]> for Scheme {
             Other(_) => {
                 // Unsafe: parse_exact already checks for a strict subset of UTF-8
                 Ok(Other(Box::new(unsafe {
-                    ByteStr::from_utf8_unchecked(s.into())
+                    ByteStr::from_utf8_unchecked(Bytes::copy_from_slice(s))
                 })).into())
             }
         }
     }
 }
 
-impl<'a> HttpTryFrom<&'a str> for Scheme {
+impl<'a> TryFrom<&'a str> for Scheme {
     type Error = InvalidUri;
     #[inline]
     fn try_from(s: &'a str) -> Result<Self, Self::Error> {
-        HttpTryFrom::try_from(s.as_bytes())
+        TryFrom::try_from(s.as_bytes())
     }
 }
 
@@ -149,15 +164,15 @@ impl FromStr for Scheme {
     type Err = InvalidUri;
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        HttpTryFrom::try_from(s)
+        TryFrom::try_from(s)
     }
 }
 
 impl From<Scheme> for Bytes {
     #[inline]
     fn from(src: Scheme) -> Self {
-        use self::Scheme2::*;
         use self::Protocol::*;
+        use self::Scheme2::*;
 
         match src.inner {
             None => Bytes::new(),
@@ -169,13 +184,13 @@ impl From<Scheme> for Bytes {
 }
 
 impl fmt::Debug for Scheme {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(self.as_str(), f)
     }
 }
 
 impl fmt::Display for Scheme {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.write_str(self.as_str())
     }
 }
@@ -228,7 +243,10 @@ impl PartialEq<Scheme> for str {
 
 /// Case-insensitive hashing
 impl Hash for Scheme {
-    fn hash<H>(&self, state: &mut H) where H: Hasher {
+    fn hash<H>(&self, state: &mut H)
+    where
+        H: Hasher,
+    {
         match self.inner {
             Scheme2::None => (),
             Scheme2::Standard(Protocol::Http) => state.write_u8(1),
@@ -344,7 +362,7 @@ impl Scheme2<usize> {
                         }
 
                         // Not a scheme
-                        if &s[i+1..i+3] != b"//" {
+                        if &s[i + 1..i + 3] != b"//" {
                             break;
                         }
 
diff --git a/src/uri/tests.rs b/src/uri/tests.rs
index 9a9ccc80..719cb94e 100644
--- a/src/uri/tests.rs
+++ b/src/uri/tests.rs
@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use super::{ErrorKind, InvalidUri, Uri, URI_CHARS, Port};
+use super::{ErrorKind, InvalidUri, Port, Uri, URI_CHARS};
 
 #[test]
 fn test_char_table() {
@@ -12,9 +12,9 @@ fn test_char_table() {
 }
 
 macro_rules! part {
-    ($s:expr) => (
+    ($s:expr) => {
         Some(&$s.parse().unwrap())
-    )
+    };
 }
 
 macro_rules! test_parse {
@@ -59,8 +59,8 @@ test_parse! {
     "/some/path/here?and=then&hello#and-bye",
     [],
 
-    scheme_part = None,
-    authority_part = None,
+    scheme = None,
+    authority = None,
     path = "/some/path/here",
     query = Some("and=then&hello"),
     host = None,
@@ -71,12 +71,12 @@ test_parse! {
     "http://127.0.0.1:61761/chunks",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1:61761"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1:61761"),
     path = "/chunks",
     query = None,
     host = Some("127.0.0.1"),
-    port_part = Port::from_str("61761").ok(),
+    port = Port::from_str("61761").ok(),
 }
 
 test_parse! {
@@ -84,12 +84,12 @@ test_parse! {
     "https://127.0.0.1:61761",
     ["https://127.0.0.1:61761/"],
 
-    scheme_part = part!("https"),
-    authority_part = part!("127.0.0.1:61761"),
+    scheme = part!("https"),
+    authority = part!("127.0.0.1:61761"),
     path = "/",
     query = None,
     host = Some("127.0.0.1"),
-    port_part = Port::from_str("61761").ok(),
+    port = Port::from_str("61761").ok(),
 }
 
 test_parse! {
@@ -97,8 +97,8 @@ test_parse! {
     "*",
     [],
 
-    scheme_part = None,
-    authority_part = None,
+    scheme = None,
+    authority = None,
     path = "*",
     query = None,
     host = None,
@@ -109,11 +109,11 @@ test_parse! {
     "localhost",
     ["LOCALHOST", "LocaLHOSt"],
 
-    scheme_part = None,
-    authority_part = part!("localhost"),
+    scheme = None,
+    authority = part!("localhost"),
     path = "",
     query = None,
-    port_part = None,
+    port = None,
     host = Some("localhost"),
 }
 
@@ -122,11 +122,11 @@ test_parse! {
     "S",
     [],
 
-    scheme_part = None,
-    authority_part = part!("S"),
+    scheme = None,
+    authority = part!("S"),
     path = "",
     query = None,
-    port_part = None,
+    port = None,
     host = Some("S"),
 }
 
@@ -135,26 +135,25 @@ test_parse! {
     "localhost:3000",
     ["localhosT:3000"],
 
-    scheme_part = None,
-    authority_part = part!("localhost:3000"),
+    scheme = None,
+    authority = part!("localhost:3000"),
     path = "",
     query = None,
     host = Some("localhost"),
-    port_part = Port::from_str("3000").ok(),
+    port = Port::from_str("3000").ok(),
 }
 
-
 test_parse! {
     test_uri_parse_absolute_with_default_port_http,
     "http://127.0.0.1:80",
     ["http://127.0.0.1:80/"],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1:80"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1:80"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = Port::from_str("80").ok(),
+    port = Port::from_str("80").ok(),
 }
 
 test_parse! {
@@ -162,12 +161,12 @@ test_parse! {
     "https://127.0.0.1:443",
     ["https://127.0.0.1:443/"],
 
-    scheme_part = part!("https"),
-    authority_part = part!("127.0.0.1:443"),
+    scheme = part!("https"),
+    authority = part!("127.0.0.1:443"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = Port::from_str("443").ok(),
+    port = Port::from_str("443").ok(),
 }
 
 test_parse! {
@@ -175,12 +174,12 @@ test_parse! {
     "http://127.0.0.1/#?",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -188,11 +187,11 @@ test_parse! {
     "http://127.0.0.1/path?",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1"),
     path = "/path",
     query = Some(""),
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -200,11 +199,11 @@ test_parse! {
     "http://127.0.0.1?foo=bar",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1"),
     path = "/",
     query = Some("foo=bar"),
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -212,11 +211,11 @@ test_parse! {
     "http://127.0.0.1#foo/bar",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -224,11 +223,11 @@ test_parse! {
     "http://127.0.0.1#foo?bar",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -236,11 +235,11 @@ test_parse! {
     "thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost",
     [],
 
-    scheme_part = None,
-    authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost"),
+    scheme = None,
+    authority = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost"),
     path = "",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -248,11 +247,11 @@ test_parse! {
     "thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234",
     [],
 
-    scheme_part = None,
-    authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234"),
+    scheme = None,
+    authority = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234"),
     path = "",
     query = None,
-    port_part = Port::from_str("1234").ok(),
+    port = Port::from_str("1234").ok(),
 }
 
 test_parse! {
@@ -260,12 +259,12 @@ test_parse! {
     "http://a:b@127.0.0.1:1234/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("a:b@127.0.0.1:1234"),
+    scheme = part!("http"),
+    authority = part!("a:b@127.0.0.1:1234"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = Port::from_str("1234").ok(),
+    port = Port::from_str("1234").ok(),
 }
 
 test_parse! {
@@ -273,12 +272,12 @@ test_parse! {
     "http://a:b@127.0.0.1/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("a:b@127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("a:b@127.0.0.1"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -286,12 +285,12 @@ test_parse! {
     "http://a@127.0.0.1/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("a@127.0.0.1"),
+    scheme = part!("http"),
+    authority = part!("a@127.0.0.1"),
     host = Some("127.0.0.1"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -299,12 +298,12 @@ test_parse! {
     "user@localhost:3000",
     [],
 
-    scheme_part = None,
-    authority_part = part!("user@localhost:3000"),
+    scheme = None,
+    authority = part!("user@localhost:3000"),
     path = "",
     query = None,
     host = Some("localhost"),
-    port_part = Port::from_str("3000").ok(),
+    port = Port::from_str("3000").ok(),
 }
 
 test_parse! {
@@ -312,12 +311,12 @@ test_parse! {
     "user:pass@localhost:3000",
     [],
 
-    scheme_part = None,
-    authority_part = part!("user:pass@localhost:3000"),
+    scheme = None,
+    authority = part!("user:pass@localhost:3000"),
     path = "",
     query = None,
     host = Some("localhost"),
-    port_part = Port::from_str("3000").ok(),
+    port = Port::from_str("3000").ok(),
 }
 
 test_parse! {
@@ -325,12 +324,12 @@ test_parse! {
     "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
+    scheme = part!("http"),
+    authority = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
     host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -338,12 +337,12 @@ test_parse! {
     "http://[::1]/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("[::1]"),
+    scheme = part!("http"),
+    authority = part!("[::1]"),
     host = Some("[::1]"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -351,12 +350,12 @@ test_parse! {
     "http://[::]/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("[::]"),
+    scheme = part!("http"),
+    authority = part!("[::]"),
     host = Some("[::]"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -364,12 +363,12 @@ test_parse! {
     "http://[2001:db8::2:1]/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("[2001:db8::2:1]"),
+    scheme = part!("http"),
+    authority = part!("[2001:db8::2:1]"),
     host = Some("[2001:db8::2:1]"),
     path = "/",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
@@ -377,12 +376,12 @@ test_parse! {
     "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008/",
     [],
 
-    scheme_part = part!("http"),
-    authority_part = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008"),
+    scheme = part!("http"),
+    authority = part!("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8008"),
     host = Some("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
     path = "/",
     query = None,
-    port_part = Port::from_str("8008").ok(),
+    port = Port::from_str("8008").ok(),
 }
 
 test_parse! {
@@ -390,12 +389,12 @@ test_parse! {
     "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478",
     [],
 
-    scheme_part = None,
-    authority_part = None,
+    scheme = None,
+    authority = None,
     host = None,
     path = "/echo/abcdefgh_i-j%20/abcdefg_i-j%20478",
     query = None,
-    port_part = None,
+    port = None,
 }
 
 test_parse! {
diff --git a/src/version.rs b/src/version.rs
index 3229dc32..d8b71306 100644
--- a/src/version.rs
+++ b/src/version.rs
@@ -37,6 +37,9 @@ impl Version {
 
     /// `HTTP/2.0`
     pub const HTTP_2: Version = Version(Http::H2);
+
+    /// `HTTP/3.0`
+    pub const HTTP_3: Version = Version(Http::H3);
 }
 
 #[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)]
@@ -45,6 +48,8 @@ enum Http {
     Http10,
     Http11,
     H2,
+    H3,
+    __NonExhaustive,
 }
 
 impl Default for Version {
@@ -55,14 +60,16 @@ impl Default for Version {
 }
 
 impl fmt::Debug for Version {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         use self::Http::*;
 
         f.write_str(match self.0 {
             Http09 => "HTTP/0.9",
             Http10 => "HTTP/1.0",
             Http11 => "HTTP/1.1",
-            H2     => "HTTP/2.0",
+            H2 => "HTTP/2.0",
+            H3 => "HTTP/3.0",
+            __NonExhaustive => unreachable!(),
         })
     }
 }
diff --git a/tests/header_map.rs b/tests/header_map.rs
index f84c0198..db909ea3 100644
--- a/tests/header_map.rs
+++ b/tests/header_map.rs
@@ -1,7 +1,5 @@
-extern crate http;
-
-use http::*;
 use http::header::*;
+use http::*;
 
 #[test]
 fn smoke() {
@@ -11,7 +9,7 @@ fn smoke() {
 
     let name: HeaderName = "hello".parse().unwrap();
 
-    match headers.entry(&name).unwrap() {
+    match headers.entry(&name) {
         Entry::Vacant(e) => {
             e.insert("world".parse().unwrap());
         }
@@ -20,7 +18,7 @@ fn smoke() {
 
     assert!(headers.get("hello").is_some());
 
-    match headers.entry(&name).unwrap() {
+    match headers.entry(&name) {
         Entry::Occupied(mut e) => {
             assert_eq!(e.get(), &"world");
 
@@ -76,9 +74,18 @@ fn drain() {
     assert!(headers.is_empty());
 
     // Insert two sequential values
-    headers.insert("hello".parse::<HeaderName>().unwrap(), "world".parse().unwrap());
-    headers.insert("zomg".parse::<HeaderName>().unwrap(), "bar".parse().unwrap());
-    headers.append("hello".parse::<HeaderName>().unwrap(), "world2".parse().unwrap());
+    headers.insert(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world".parse().unwrap(),
+    );
+    headers.insert(
+        "zomg".parse::<HeaderName>().unwrap(),
+        "bar".parse().unwrap(),
+    );
+    headers.append(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world2".parse().unwrap(),
+    );
 
     // Drain...
     {
@@ -140,15 +147,30 @@ fn drain_forget() {
 fn drain_entry() {
     let mut headers = HeaderMap::new();
 
-    headers.insert("hello".parse::<HeaderName>().unwrap(), "world".parse().unwrap());
-    headers.insert("zomg".parse::<HeaderName>().unwrap(), "foo".parse().unwrap());
-    headers.append("hello".parse::<HeaderName>().unwrap(), "world2".parse().unwrap());
-    headers.insert("more".parse::<HeaderName>().unwrap(), "words".parse().unwrap());
-    headers.append("more".parse::<HeaderName>().unwrap(), "insertions".parse().unwrap());
+    headers.insert(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world".parse().unwrap(),
+    );
+    headers.insert(
+        "zomg".parse::<HeaderName>().unwrap(),
+        "foo".parse().unwrap(),
+    );
+    headers.append(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world2".parse().unwrap(),
+    );
+    headers.insert(
+        "more".parse::<HeaderName>().unwrap(),
+        "words".parse().unwrap(),
+    );
+    headers.append(
+        "more".parse::<HeaderName>().unwrap(),
+        "insertions".parse().unwrap(),
+    );
 
     // Using insert
     {
-        let mut e = match headers.entry("hello").unwrap() {
+        let mut e = match headers.entry("hello") {
             Entry::Occupied(e) => e,
             _ => panic!(),
         };
@@ -167,10 +189,16 @@ fn eq() {
 
     assert_eq!(a, b);
 
-    a.insert("hello".parse::<HeaderName>().unwrap(), "world".parse().unwrap());
+    a.insert(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world".parse().unwrap(),
+    );
     assert_ne!(a, b);
 
-    b.insert("hello".parse::<HeaderName>().unwrap(), "world".parse().unwrap());
+    b.insert(
+        "hello".parse::<HeaderName>().unwrap(),
+        "world".parse().unwrap(),
+    );
     assert_eq!(a, b);
 
     a.insert("foo".parse::<HeaderName>().unwrap(), "bar".parse().unwrap());
@@ -228,13 +256,18 @@ fn insert_all_std_headers() {
     for (i, hdr) in STD.iter().enumerate() {
         m.insert(hdr.clone(), hdr.as_str().parse().unwrap());
 
-        for j in 0..(i+1) {
+        for j in 0..(i + 1) {
             assert_eq!(m[&STD[j]], STD[j].as_str());
         }
 
         if i != 0 {
-            for j in (i+1)..STD.len() {
-                assert!(m.get(&STD[j]).is_none(), "contained {}; j={}", STD[j].as_str(), j);
+            for j in (i + 1)..STD.len() {
+                assert!(
+                    m.get(&STD[j]).is_none(),
+                    "contained {}; j={}",
+                    STD[j].as_str(),
+                    j
+                );
             }
         }
     }
@@ -248,11 +281,11 @@ fn insert_79_custom_std_headers() {
     for (i, hdr) in hdrs.iter().enumerate() {
         h.insert(hdr.clone(), hdr.as_str().parse().unwrap());
 
-        for j in 0..(i+1) {
+        for j in 0..(i + 1) {
             assert_eq!(h[&hdrs[j]], hdrs[j].as_str());
         }
 
-        for j in (i+1)..hdrs.len() {
+        for j in (i + 1)..hdrs.len() {
             assert!(h.get(&hdrs[j]).is_none());
         }
     }
@@ -266,7 +299,8 @@ fn append_multiple_values() {
     map.append(header::CONTENT_TYPE, "html".parse().unwrap());
     map.append(header::CONTENT_TYPE, "xml".parse().unwrap());
 
-    let vals = map.get_all(&header::CONTENT_TYPE)
+    let vals = map
+        .get_all(&header::CONTENT_TYPE)
         .iter()
         .collect::<Vec<_>>();
 
@@ -274,10 +308,12 @@ fn append_multiple_values() {
 }
 
 fn custom_std(n: usize) -> Vec<HeaderName> {
-    (0..n).map(|i| {
-        let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
-        s.parse().unwrap()
-    }).collect()
+    (0..n)
+        .map(|i| {
+            let s = format!("{}-{}", STD[i % STD.len()].as_str(), i);
+            s.parse().unwrap()
+        })
+        .collect()
 }
 
 const STD: &'static [HeaderName] = &[
diff --git a/tests/header_map_fuzz.rs b/tests/header_map_fuzz.rs
index 03318cdf..fbcd8d2d 100644
--- a/tests/header_map_fuzz.rs
+++ b/tests/header_map_fuzz.rs
@@ -1,12 +1,10 @@
-extern crate http;
-extern crate rand;
-extern crate quickcheck;
-
-use http::*;
 use http::header::*;
+use http::*;
 
 use quickcheck::{Arbitrary, Gen, QuickCheck, TestResult};
-use rand::{StdRng, SeedableRng, Rng};
+use rand::rngs::StdRng;
+use rand::seq::SliceRandom;
+use rand::{Rng, SeedableRng};
 
 use std::collections::HashMap;
 
@@ -17,14 +15,13 @@ fn header_map_fuzz() {
         TestResult::from_bool(true)
     }
 
-    QuickCheck::new()
-        .quickcheck(prop as fn(Fuzz) -> TestResult)
+    QuickCheck::new().quickcheck(prop as fn(Fuzz) -> TestResult)
 }
 
 #[derive(Debug, Clone)]
 struct Fuzz {
     // The magic seed that makes the test case reproducible
-    seed: [usize; 4],
+    seed: [u8; 32],
 
     // Actions to perform
     steps: Vec<Step>,
@@ -49,8 +46,8 @@ struct Step {
 #[derive(Debug, Clone)]
 enum Action {
     Insert {
-        name: HeaderName, // Name to insert
-        val: HeaderValue, // Value to insert
+        name: HeaderName,         // Name to insert
+        val: HeaderValue,         // Value to insert
         old: Option<HeaderValue>, // Old value
     },
     Append {
@@ -59,7 +56,7 @@ enum Action {
         ret: bool,
     },
     Remove {
-        name: HeaderName, // Name to remove
+        name: HeaderName,         // Name to remove
         val: Option<HeaderValue>, // Value to get
     },
 }
@@ -71,9 +68,9 @@ struct AltMap {
 }
 
 impl Fuzz {
-    fn new(seed: [usize; 4]) -> Fuzz {
+    fn new(seed: [u8; 32]) -> Fuzz {
         // Seed the RNG
-        let mut rng = StdRng::from_seed(&seed);
+        let mut rng = StdRng::from_seed(seed);
 
         let mut steps = vec![];
         let mut expect = AltMap::default();
@@ -113,7 +110,7 @@ impl Fuzz {
 
 impl Arbitrary for Fuzz {
     fn arbitrary<G: Gen>(g: &mut G) -> Self {
-        Fuzz::new(quickcheck::Rng::gen(g))
+        Fuzz::new(Rng::gen(g))
     }
 }
 
@@ -129,9 +126,7 @@ impl AltMap {
 
     /// This will also apply the action against `self`
     fn gen_action(&mut self, weight: &Weight, rng: &mut StdRng) -> Action {
-        let sum = weight.insert +
-            weight.remove +
-            weight.append;
+        let sum = weight.insert + weight.remove + weight.append;
 
         let mut num = rng.gen_range(0, sum);
 
@@ -180,8 +175,7 @@ impl AltMap {
         let name = self.gen_name(-5, rng);
         let val = gen_header_value(rng);
 
-        let vals = self.map.entry(name.clone())
-            .or_insert(vec![]);
+        let vals = self.map.entry(name.clone()).or_insert(vec![]);
 
         let ret = !vals.is_empty();
         vals.push(val.clone());
@@ -195,7 +189,7 @@ impl AltMap {
 
     /// Negative numbers weigh finding an existing header higher
     fn gen_name(&self, weight: i32, rng: &mut StdRng) -> HeaderName {
-        let mut existing = rng.gen_weighted_bool(weight.abs() as u32);
+        let mut existing = rng.gen_ratio(1, weight.abs() as u32);
 
         if weight < 0 {
             existing = !existing;
@@ -268,82 +262,90 @@ impl Action {
 }
 
 fn gen_header_name(g: &mut StdRng) -> HeaderName {
-    if g.gen_weighted_bool(2) {
-        g.choose(&[
-            header::ACCEPT,
-            header::ACCEPT_CHARSET,
-            header::ACCEPT_ENCODING,
-            header::ACCEPT_LANGUAGE,
-            header::ACCEPT_RANGES,
-            header::ACCESS_CONTROL_ALLOW_CREDENTIALS,
-            header::ACCESS_CONTROL_ALLOW_HEADERS,
-            header::ACCESS_CONTROL_ALLOW_METHODS,
-            header::ACCESS_CONTROL_ALLOW_ORIGIN,
-            header::ACCESS_CONTROL_EXPOSE_HEADERS,
-            header::ACCESS_CONTROL_MAX_AGE,
-            header::ACCESS_CONTROL_REQUEST_HEADERS,
-            header::ACCESS_CONTROL_REQUEST_METHOD,
-            header::AGE,
-            header::ALLOW,
-            header::ALT_SVC,
-            header::AUTHORIZATION,
-            header::CACHE_CONTROL,
-            header::CONNECTION,
-            header::CONTENT_DISPOSITION,
-            header::CONTENT_ENCODING,
-            header::CONTENT_LANGUAGE,
-            header::CONTENT_LENGTH,
-            header::CONTENT_LOCATION,
-            header::CONTENT_RANGE,
-            header::CONTENT_SECURITY_POLICY,
-            header::CONTENT_SECURITY_POLICY_REPORT_ONLY,
-            header::CONTENT_TYPE,
-            header::COOKIE,
-            header::DNT,
-            header::DATE,
-            header::ETAG,
-            header::EXPECT,
-            header::EXPIRES,
-            header::FORWARDED,
-            header::FROM,
-            header::HOST,
-            header::IF_MATCH,
-            header::IF_MODIFIED_SINCE,
-            header::IF_NONE_MATCH,
-            header::IF_RANGE,
-            header::IF_UNMODIFIED_SINCE,
-            header::LAST_MODIFIED,
-            header::LINK,
-            header::LOCATION,
-            header::MAX_FORWARDS,
-            header::ORIGIN,
-            header::PRAGMA,
-            header::PROXY_AUTHENTICATE,
-            header::PROXY_AUTHORIZATION,
-            header::PUBLIC_KEY_PINS,
-            header::PUBLIC_KEY_PINS_REPORT_ONLY,
-            header::RANGE,
-            header::REFERER,
-            header::REFERRER_POLICY,
-            header::RETRY_AFTER,
-            header::SERVER,
-            header::SET_COOKIE,
-            header::STRICT_TRANSPORT_SECURITY,
-            header::TE,
-            header::TRAILER,
-            header::TRANSFER_ENCODING,
-            header::USER_AGENT,
-            header::UPGRADE,
-            header::UPGRADE_INSECURE_REQUESTS,
-            header::VARY,
-            header::VIA,
-            header::WARNING,
-            header::WWW_AUTHENTICATE,
-            header::X_CONTENT_TYPE_OPTIONS,
-            header::X_DNS_PREFETCH_CONTROL,
-            header::X_FRAME_OPTIONS,
-            header::X_XSS_PROTECTION,
-        ]).unwrap().clone()
+    const STANDARD_HEADERS: &'static [HeaderName] = &[
+        header::ACCEPT,
+        header::ACCEPT_CHARSET,
+        header::ACCEPT_ENCODING,
+        header::ACCEPT_LANGUAGE,
+        header::ACCEPT_RANGES,
+        header::ACCESS_CONTROL_ALLOW_CREDENTIALS,
+        header::ACCESS_CONTROL_ALLOW_HEADERS,
+        header::ACCESS_CONTROL_ALLOW_METHODS,
+        header::ACCESS_CONTROL_ALLOW_ORIGIN,
+        header::ACCESS_CONTROL_EXPOSE_HEADERS,
+        header::ACCESS_CONTROL_MAX_AGE,
+        header::ACCESS_CONTROL_REQUEST_HEADERS,
+        header::ACCESS_CONTROL_REQUEST_METHOD,
+        header::AGE,
+        header::ALLOW,
+        header::ALT_SVC,
+        header::AUTHORIZATION,
+        header::CACHE_CONTROL,
+        header::CONNECTION,
+        header::CONTENT_DISPOSITION,
+        header::CONTENT_ENCODING,
+        header::CONTENT_LANGUAGE,
+        header::CONTENT_LENGTH,
+        header::CONTENT_LOCATION,
+        header::CONTENT_RANGE,
+        header::CONTENT_SECURITY_POLICY,
+        header::CONTENT_SECURITY_POLICY_REPORT_ONLY,
+        header::CONTENT_TYPE,
+        header::COOKIE,
+        header::DNT,
+        header::DATE,
+        header::ETAG,
+        header::EXPECT,
+        header::EXPIRES,
+        header::FORWARDED,
+        header::FROM,
+        header::HOST,
+        header::IF_MATCH,
+        header::IF_MODIFIED_SINCE,
+        header::IF_NONE_MATCH,
+        header::IF_RANGE,
+        header::IF_UNMODIFIED_SINCE,
+        header::LAST_MODIFIED,
+        header::LINK,
+        header::LOCATION,
+        header::MAX_FORWARDS,
+        header::ORIGIN,
+        header::PRAGMA,
+        header::PROXY_AUTHENTICATE,
+        header::PROXY_AUTHORIZATION,
+        header::PUBLIC_KEY_PINS,
+        header::PUBLIC_KEY_PINS_REPORT_ONLY,
+        header::RANGE,
+        header::REFERER,
+        header::REFERRER_POLICY,
+        header::REFRESH,
+        header::RETRY_AFTER,
+        header::SEC_WEBSOCKET_ACCEPT,
+        header::SEC_WEBSOCKET_EXTENSIONS,
+        header::SEC_WEBSOCKET_KEY,
+        header::SEC_WEBSOCKET_PROTOCOL,
+        header::SEC_WEBSOCKET_VERSION,
+        header::SERVER,
+        header::SET_COOKIE,
+        header::STRICT_TRANSPORT_SECURITY,
+        header::TE,
+        header::TRAILER,
+        header::TRANSFER_ENCODING,
+        header::UPGRADE,
+        header::UPGRADE_INSECURE_REQUESTS,
+        header::USER_AGENT,
+        header::VARY,
+        header::VIA,
+        header::WARNING,
+        header::WWW_AUTHENTICATE,
+        header::X_CONTENT_TYPE_OPTIONS,
+        header::X_DNS_PREFETCH_CONTROL,
+        header::X_FRAME_OPTIONS,
+        header::X_XSS_PROTECTION,
+    ];
+
+    if g.gen_ratio(1, 2) {
+        STANDARD_HEADERS.choose(g).unwrap().clone()
     } else {
         let value = gen_string(g, 1, 25);
         HeaderName::from_bytes(value.as_bytes()).unwrap()
@@ -356,10 +358,15 @@ fn gen_header_value(g: &mut StdRng) -> HeaderValue {
 }
 
 fn gen_string(g: &mut StdRng, min: usize, max: usize) -> String {
-    let bytes: Vec<_> = (min..max).map(|_| {
-        // Chars to pick from
-        g.choose(b"ABCDEFGHIJKLMNOPQRSTUVabcdefghilpqrstuvwxyz----").unwrap().clone()
-    }).collect();
+    let bytes: Vec<_> = (min..max)
+        .map(|_| {
+            // Chars to pick from
+            b"ABCDEFGHIJKLMNOPQRSTUVabcdefghilpqrstuvwxyz----"
+                .choose(g)
+                .unwrap()
+                .clone()
+        })
+        .collect();
 
     String::from_utf8(bytes).unwrap()
 }
diff --git a/tests/status_code.rs b/tests/status_code.rs
index 72ba810c..80df748e 100644
--- a/tests/status_code.rs
+++ b/tests/status_code.rs
@@ -1,14 +1,16 @@
-extern crate http;
-
 use http::*;
 
 #[test]
 fn from_bytes() {
-    for ok in &["100", "101", "199", "200", "250", "299", "321", "399", "499", "599"] {
+    for ok in &[
+        "100", "101", "199", "200", "250", "299", "321", "399", "499", "599",
+    ] {
         assert!(StatusCode::from_bytes(ok.as_bytes()).is_ok());
     }
 
-    for not_ok in &["0", "00", "10", "40", "99", "000", "010", "099", "600", "610", "999"] {
+    for not_ok in &[
+        "0", "00", "10", "40", "99", "000", "010", "099", "600", "610", "999",
+    ] {
         assert!(StatusCode::from_bytes(not_ok.as_bytes()).is_err());
     }
 }
