@@ -30,7 +30,7 @@ impl From<Infallible> for Error {
30
30
}
31
31
32
32
///
33
- #[ derive( Debug ) ]
33
+ #[ derive( Debug , Clone ) ]
34
34
pub enum UrlKind {
35
35
///
36
36
Url ,
@@ -93,16 +93,7 @@ pub fn parse(input: &BStr) -> Result<crate::Url, Error> {
93
93
}
94
94
95
95
fn parse_url ( input : & BStr ) -> Result < crate :: Url , Error > {
96
- let input = std:: str:: from_utf8 ( input) . map_err ( |source| Error :: Utf8 {
97
- url : input. to_owned ( ) ,
98
- kind : UrlKind :: Url ,
99
- source,
100
- } ) ?;
101
- let url = url:: Url :: parse ( input) . map_err ( |source| Error :: Url {
102
- url : input. to_owned ( ) ,
103
- kind : UrlKind :: Url ,
104
- source,
105
- } ) ?;
96
+ let ( input, url) = input_to_utf8_and_url ( input, UrlKind :: Url ) ?;
106
97
107
98
let scheme = url. scheme ( ) . into ( ) ;
108
99
@@ -133,11 +124,7 @@ fn parse_url(input: &BStr) -> Result<crate::Url, Error> {
133
124
}
134
125
135
126
fn parse_scp ( input : & BStr , colon : usize ) -> Result < crate :: Url , Error > {
136
- let input = std:: str:: from_utf8 ( input) . map_err ( |source| Error :: Utf8 {
137
- url : input. to_owned ( ) ,
138
- kind : UrlKind :: Scp ,
139
- source,
140
- } ) ?;
127
+ let input = input_to_utf8 ( input, UrlKind :: Scp ) ?;
141
128
142
129
// TODO: this incorrectly splits at IPv6 addresses, check for `[]` before splitting
143
130
let ( host, path) = input. split_at ( colon) ;
@@ -176,16 +163,7 @@ fn parse_scp(input: &BStr, colon: usize) -> Result<crate::Url, Error> {
176
163
}
177
164
178
165
fn parse_file_url ( input : & BStr , protocol_colon : usize ) -> Result < crate :: Url , Error > {
179
- let input = std:: str:: from_utf8 ( input) . map_err ( |source| Error :: Utf8 {
180
- url : input. to_owned ( ) ,
181
- kind : UrlKind :: Url ,
182
- source,
183
- } ) ?;
184
- let url = url:: Url :: parse ( input) . map_err ( |source| Error :: Url {
185
- url : input. to_owned ( ) ,
186
- kind : UrlKind :: Url ,
187
- source,
188
- } ) ?;
166
+ let ( input, url) = input_to_utf8_and_url ( input, UrlKind :: Url ) ?;
189
167
190
168
if !input[ protocol_colon + 3 ..] . contains ( '/' ) {
191
169
return Err ( Error :: MissingRepositoryPath {
@@ -215,3 +193,26 @@ fn parse_local(input: &BStr, was_in_url_format: bool) -> Result<crate::Url, Erro
215
193
path : input. into ( ) ,
216
194
} )
217
195
}
196
+
197
+ /// Helper function to turn a BStr into an str. The kind is only used for the construction of the
198
+ /// error variant.
199
+ fn input_to_utf8 ( input : & BStr , kind : UrlKind ) -> Result < & str , Error > {
200
+ std:: str:: from_utf8 ( input) . map_err ( |source| Error :: Utf8 {
201
+ url : input. to_owned ( ) ,
202
+ kind,
203
+ source,
204
+ } )
205
+ }
206
+
207
+ /// Helper function to turn a BStr into an Url. The kind is only used for the construction of the
208
+ /// error variant.
209
+ fn input_to_utf8_and_url ( input : & BStr , kind : UrlKind ) -> Result < ( & str , url:: Url ) , Error > {
210
+ let input = input_to_utf8 ( input, kind. clone ( ) ) ?;
211
+ url:: Url :: parse ( input)
212
+ . map ( |url| ( input, url) )
213
+ . map_err ( |source| Error :: Url {
214
+ url : input. to_owned ( ) ,
215
+ kind,
216
+ source,
217
+ } )
218
+ }
0 commit comments