2424
2525use crate :: byte_str:: ByteStr ;
2626use crate :: HttpTryFrom ;
27+ use std:: convert:: TryFrom ;
2728
2829use bytes:: Bytes ;
2930
@@ -241,8 +242,7 @@ impl Uri {
241242
242243 /// Attempt to convert a `Uri` from `Bytes`
243244 ///
244- /// This function will be replaced by a `TryFrom` implementation once the
245- /// trait lands in stable.
245+ /// This function has been replaced by `TryFrom` implementation.
246246 ///
247247 /// # Examples
248248 ///
@@ -262,53 +262,7 @@ impl Uri {
262262 /// # }
263263 /// ```
264264 pub fn from_shared ( s : Bytes ) -> Result < Uri , InvalidUriBytes > {
265- use self :: ErrorKind :: * ;
266-
267- if s. len ( ) > MAX_LEN {
268- return Err ( TooLong . into ( ) ) ;
269- }
270-
271- match s. len ( ) {
272- 0 => {
273- return Err ( Empty . into ( ) ) ;
274- }
275- 1 => match s[ 0 ] {
276- b'/' => {
277- return Ok ( Uri {
278- scheme : Scheme :: empty ( ) ,
279- authority : Authority :: empty ( ) ,
280- path_and_query : PathAndQuery :: slash ( ) ,
281- } ) ;
282- }
283- b'*' => {
284- return Ok ( Uri {
285- scheme : Scheme :: empty ( ) ,
286- authority : Authority :: empty ( ) ,
287- path_and_query : PathAndQuery :: star ( ) ,
288- } ) ;
289- }
290- _ => {
291- let authority = Authority :: from_shared ( s) ?;
292-
293- return Ok ( Uri {
294- scheme : Scheme :: empty ( ) ,
295- authority : authority,
296- path_and_query : PathAndQuery :: empty ( ) ,
297- } ) ;
298- }
299- } ,
300- _ => { }
301- }
302-
303- if s[ 0 ] == b'/' {
304- return Ok ( Uri {
305- scheme : Scheme :: empty ( ) ,
306- authority : Authority :: empty ( ) ,
307- path_and_query : PathAndQuery :: from_shared ( s) ?,
308- } ) ;
309- }
310-
311- parse_full ( s)
265+ TryFrom :: try_from ( s)
312266 }
313267
314268 /// Convert a `Uri` from a static string.
@@ -679,6 +633,80 @@ impl Uri {
679633 }
680634}
681635
636+ impl TryFrom < Bytes > for Uri {
637+ type Error = InvalidUriBytes ;
638+
639+ /// Attempt to convert a `Uri` from `Bytes`
640+ ///
641+ /// # Examples
642+ ///
643+ /// ```
644+ /// # extern crate http;
645+ /// # use http::uri::*;
646+ /// extern crate bytes;
647+ ///
648+ /// use std::convert::TryFrom;
649+ /// use bytes::Bytes;
650+ ///
651+ /// # pub fn main() {
652+ /// let bytes = Bytes::from("http://example.com/foo");
653+ /// let uri = Uri::try_from(bytes).unwrap();
654+ ///
655+ /// assert_eq!(uri.host().unwrap(), "example.com");
656+ /// assert_eq!(uri.path(), "/foo");
657+ /// # }
658+ /// ```
659+ fn try_from ( s : Bytes ) -> Result < Uri , Self :: Error > {
660+ use self :: ErrorKind :: * ;
661+
662+ if s. len ( ) > MAX_LEN {
663+ return Err ( TooLong . into ( ) ) ;
664+ }
665+
666+ match s. len ( ) {
667+ 0 => {
668+ return Err ( Empty . into ( ) ) ;
669+ }
670+ 1 => match s[ 0 ] {
671+ b'/' => {
672+ return Ok ( Uri {
673+ scheme : Scheme :: empty ( ) ,
674+ authority : Authority :: empty ( ) ,
675+ path_and_query : PathAndQuery :: slash ( ) ,
676+ } ) ;
677+ }
678+ b'*' => {
679+ return Ok ( Uri {
680+ scheme : Scheme :: empty ( ) ,
681+ authority : Authority :: empty ( ) ,
682+ path_and_query : PathAndQuery :: star ( ) ,
683+ } ) ;
684+ }
685+ _ => {
686+ let authority = Authority :: from_shared ( s) ?;
687+
688+ return Ok ( Uri {
689+ scheme : Scheme :: empty ( ) ,
690+ authority : authority,
691+ path_and_query : PathAndQuery :: empty ( ) ,
692+ } ) ;
693+ }
694+ } ,
695+ _ => { }
696+ }
697+
698+ if s[ 0 ] == b'/' {
699+ return Ok ( Uri {
700+ scheme : Scheme :: empty ( ) ,
701+ authority : Authority :: empty ( ) ,
702+ path_and_query : PathAndQuery :: from_shared ( s) ?,
703+ } ) ;
704+ }
705+
706+ parse_full ( s)
707+ }
708+ }
709+
682710impl < ' a > HttpTryFrom < & ' a str > for Uri {
683711 type Error = InvalidUri ;
684712
0 commit comments