6
6
// option. This file may not be copied, modified, or distributed
7
7
// except according to those terms.
8
8
9
+ use alloc:: borrow:: Cow ;
9
10
use alloc:: string:: String ;
10
- use alloc:: string:: ToString ;
11
11
use core:: fmt:: { self , Formatter , Write } ;
12
12
use core:: str;
13
13
@@ -329,6 +329,10 @@ impl Iterator for Input<'_> {
329
329
fn next ( & mut self ) -> Option < char > {
330
330
self . chars . by_ref ( ) . find ( |& c| !ascii_tab_or_new_line ( c) )
331
331
}
332
+
333
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
334
+ ( 0 , Some ( self . chars . as_str ( ) . len ( ) ) )
335
+ }
332
336
}
333
337
334
338
pub struct Parser < ' a > {
@@ -987,7 +991,7 @@ impl<'a> Parser<'a> {
987
991
pub fn parse_host (
988
992
mut input : Input < ' _ > ,
989
993
scheme_type : SchemeType ,
990
- ) -> ParseResult < ( Host < String > , Input < ' _ > ) > {
994
+ ) -> ParseResult < ( Host < Cow < ' _ , str > > , Input < ' _ > ) > {
991
995
if scheme_type. is_file ( ) {
992
996
return Parser :: get_file_host ( input) ;
993
997
}
@@ -1018,34 +1022,34 @@ impl<'a> Parser<'a> {
1018
1022
}
1019
1023
bytes += c. len_utf8 ( ) ;
1020
1024
}
1021
- let replaced: String ;
1022
1025
let host_str;
1023
1026
{
1024
1027
let host_input = input. by_ref ( ) . take ( non_ignored_chars) ;
1025
1028
if has_ignored_chars {
1026
- replaced = host_input. collect ( ) ;
1027
- host_str = & * replaced
1029
+ host_str = Cow :: Owned ( host_input. collect ( ) ) ;
1028
1030
} else {
1029
1031
for _ in host_input { }
1030
- host_str = & input_str[ ..bytes]
1032
+ host_str = Cow :: Borrowed ( & input_str[ ..bytes] ) ;
1031
1033
}
1032
1034
}
1033
1035
if scheme_type == SchemeType :: SpecialNotFile && host_str. is_empty ( ) {
1034
1036
return Err ( ParseError :: EmptyHost ) ;
1035
1037
}
1036
1038
if !scheme_type. is_special ( ) {
1037
- let host = Host :: parse_opaque ( host_str) ?;
1039
+ let host = Host :: parse_opaque_cow ( host_str) ?;
1038
1040
return Ok ( ( host, input) ) ;
1039
1041
}
1040
- let host = Host :: parse ( host_str) ?;
1042
+ let host = Host :: parse_cow ( host_str) ?;
1041
1043
Ok ( ( host, input) )
1042
1044
}
1043
1045
1044
- fn get_file_host ( input : Input < ' _ > ) -> ParseResult < ( Host < String > , Input < ' _ > ) > {
1046
+ fn get_file_host ( input : Input < ' _ > ) -> ParseResult < ( Host < Cow < ' _ , str > > , Input < ' _ > ) > {
1045
1047
let ( _, host_str, remaining) = Parser :: file_host ( input) ?;
1046
1048
let host = match Host :: parse ( & host_str) ? {
1047
- Host :: Domain ( ref d) if d == "localhost" => Host :: Domain ( "" . to_string ( ) ) ,
1048
- host => host,
1049
+ Host :: Domain ( ref d) if d == "localhost" => Host :: Domain ( Cow :: Borrowed ( "" ) ) ,
1050
+ Host :: Domain ( s) => Host :: Domain ( Cow :: Owned ( s) ) ,
1051
+ Host :: Ipv4 ( ip) => Host :: Ipv4 ( ip) ,
1052
+ Host :: Ipv6 ( ip) => Host :: Ipv6 ( ip) ,
1049
1053
} ;
1050
1054
Ok ( ( host, remaining) )
1051
1055
}
@@ -1060,7 +1064,7 @@ impl<'a> Parser<'a> {
1060
1064
has_host = false ;
1061
1065
HostInternal :: None
1062
1066
} else {
1063
- match Host :: parse ( & host_str) ? {
1067
+ match Host :: parse_cow ( host_str) ? {
1064
1068
Host :: Domain ( ref d) if d == "localhost" => {
1065
1069
has_host = false ;
1066
1070
HostInternal :: None
@@ -1075,7 +1079,7 @@ impl<'a> Parser<'a> {
1075
1079
Ok ( ( has_host, host, remaining) )
1076
1080
}
1077
1081
1078
- pub fn file_host ( input : Input ) -> ParseResult < ( bool , String , Input ) > {
1082
+ pub fn file_host ( input : Input < ' _ > ) -> ParseResult < ( bool , Cow < ' _ , str > , Input < ' _ > ) > {
1079
1083
// Undo the Input abstraction here to avoid allocating in the common case
1080
1084
// where the host part of the input does not contain any tab or newline
1081
1085
let input_str = input. chars . as_str ( ) ;
@@ -1090,23 +1094,21 @@ impl<'a> Parser<'a> {
1090
1094
}
1091
1095
bytes += c. len_utf8 ( ) ;
1092
1096
}
1093
- let replaced: String ;
1094
1097
let host_str;
1095
1098
let mut remaining = input. clone ( ) ;
1096
1099
{
1097
1100
let host_input = remaining. by_ref ( ) . take ( non_ignored_chars) ;
1098
1101
if has_ignored_chars {
1099
- replaced = host_input. collect ( ) ;
1100
- host_str = & * replaced
1102
+ host_str = Cow :: Owned ( host_input. collect ( ) ) ;
1101
1103
} else {
1102
1104
for _ in host_input { }
1103
- host_str = & input_str[ ..bytes]
1105
+ host_str = Cow :: Borrowed ( & input_str[ ..bytes] ) ;
1104
1106
}
1105
1107
}
1106
- if is_windows_drive_letter ( host_str) {
1107
- return Ok ( ( false , "" . to_string ( ) , input) ) ;
1108
+ if is_windows_drive_letter ( & host_str) {
1109
+ return Ok ( ( false , "" . into ( ) , input) ) ;
1108
1110
}
1109
- Ok ( ( true , host_str. to_string ( ) , remaining) )
1111
+ Ok ( ( true , host_str, remaining) )
1110
1112
}
1111
1113
1112
1114
pub fn parse_port < P > (
0 commit comments