@@ -14,7 +14,7 @@ use core::str;
14
14
use std:: fmt;
15
15
use url:: Url ;
16
16
17
- use getset:: { CloneGetters , CopyGetters , Setters } ;
17
+ use getset:: { CopyGetters , Getters , Setters } ;
18
18
#[ cfg( feature = "log" ) ]
19
19
use log:: debug;
20
20
use nom:: Finish ;
@@ -42,45 +42,82 @@ pub(crate) enum GitUrlParseHint {
42
42
/// GitUrl is an input url used by git.
43
43
/// Parsing of the url inspired by rfc3986, but does not strictly cover the spec
44
44
/// Optional, but by default, uses the `url` crate to perform a final validation of the parsing effort
45
- #[ derive( Clone , CopyGetters , CloneGetters , Debug , Default , Setters , PartialEq , Eq ) ]
45
+ #[ derive( Clone , CopyGetters , Getters , Debug , Default , Setters , PartialEq , Eq ) ]
46
46
#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
47
- pub struct GitUrl < ' url > {
47
+ #[ getset( set = "pub(crate)" ) ]
48
+ pub struct GitUrl {
48
49
/// scheme name (i.e. `scheme://`)
49
- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
50
- scheme : Option < & ' url str > ,
50
+ scheme : Option < String > ,
51
51
/// user name userinfo
52
- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
53
- user : Option < & ' url str > ,
52
+ user : Option < String > ,
54
53
/// password userinfo provided with `user` (i.e. `user`:`password`@...)
55
- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
56
- password : Option < & ' url str > ,
54
+ password : Option < String > ,
57
55
/// The hostname or IP of the repo host
58
- #[ getset( get_copy = "pub" ) ]
59
- host : Option < & ' url str > ,
56
+ host : Option < String > ,
60
57
/// The port number of the repo host, if specified
61
58
#[ getset( get_copy = "pub" ) ]
62
59
port : Option < u16 > ,
63
60
/// File or network path to repo
64
- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
65
- path : & ' url str ,
61
+ path : String ,
66
62
/// If we should print `scheme://` from input or derived during parsing
67
- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
63
+ #[ getset( get_copy = "pub" ) ]
68
64
print_scheme : bool ,
69
65
/// Pattern style of url derived during parsing
70
- #[ getset( get_copy = "pub(crate) " ) ]
66
+ #[ getset( get_copy = "pub" ) ]
71
67
hint : GitUrlParseHint ,
72
68
}
73
69
74
70
/// Build the printable GitUrl from its components
75
- impl fmt:: Display for GitUrl < ' _ > {
71
+ impl fmt:: Display for GitUrl {
76
72
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
77
73
let git_url_str = self . display ( ) ;
78
74
79
75
write ! ( f, "{git_url_str}" , )
80
76
}
81
77
}
82
78
83
- impl < ' url > GitUrl < ' url > {
79
+ impl GitUrl {
80
+ /// scheme name (i.e. `scheme://`)
81
+ pub fn scheme ( & self ) -> Option < & str > {
82
+ if let Some ( s) = & self . scheme {
83
+ Some ( & s[ ..] )
84
+ } else {
85
+ None
86
+ }
87
+ }
88
+
89
+ /// user name userinfo
90
+ pub fn user ( & self ) -> Option < & str > {
91
+ if let Some ( u) = & self . user {
92
+ Some ( & u[ ..] )
93
+ } else {
94
+ None
95
+ }
96
+ }
97
+
98
+ /// password userinfo provided with `user` (i.e. `user`:`password`@...)
99
+ pub fn password ( & self ) -> Option < & str > {
100
+ if let Some ( p) = & self . password {
101
+ Some ( & p[ ..] )
102
+ } else {
103
+ None
104
+ }
105
+ }
106
+
107
+ /// The hostname or IP of the repo host
108
+ pub fn host ( & self ) -> Option < & str > {
109
+ if let Some ( h) = & self . host {
110
+ Some ( & h[ ..] )
111
+ } else {
112
+ None
113
+ }
114
+ }
115
+
116
+ /// File or network path to repo
117
+ pub fn path ( & self ) -> & str {
118
+ & self . path [ ..]
119
+ }
120
+
84
121
/// Wrapper function for the default output mode via [`Display`](std::fmt::Display) trait
85
122
fn display ( & self ) -> String {
86
123
self . build_string ( false )
@@ -142,7 +179,7 @@ impl<'url> GitUrl<'url> {
142
179
}
143
180
144
181
#[ cfg( feature = "url" ) ]
145
- impl < ' url > TryFrom < & GitUrl < ' url > > for Url {
182
+ impl TryFrom < & GitUrl > for Url {
146
183
type Error = url:: ParseError ;
147
184
fn try_from ( value : & GitUrl ) -> Result < Self , Self :: Error > {
148
185
// Since we don't fully implement any spec, we'll rely on the url crate
@@ -151,15 +188,15 @@ impl<'url> TryFrom<&GitUrl<'url>> for Url {
151
188
}
152
189
153
190
#[ cfg( feature = "url" ) ]
154
- impl < ' url > TryFrom < GitUrl < ' url > > for Url {
191
+ impl TryFrom < GitUrl > for Url {
155
192
type Error = url:: ParseError ;
156
193
fn try_from ( value : GitUrl ) -> Result < Self , Self :: Error > {
157
194
// Since we don't fully implement any spec, we'll rely on the url crate
158
195
Url :: parse ( & value. url_compat_display ( ) )
159
196
}
160
197
}
161
198
162
- impl < ' url > GitUrl < ' url > {
199
+ impl GitUrl {
163
200
/// Returns `GitUrl` after removing all user info values
164
201
pub fn trim_auth ( & self ) -> GitUrl {
165
202
let mut new_giturl = self . clone ( ) ;
@@ -181,7 +218,9 @@ impl<'url> GitUrl<'url> {
181
218
/// # Ok(())
182
219
/// # }
183
220
/// ```
184
- pub fn parse ( input : & ' url str ) -> Result < Self , GitUrlParseError > {
221
+ pub fn parse ( input : & str ) -> Result < Self , GitUrlParseError > {
222
+ let mut git_url_result = GitUrl :: default ( ) ;
223
+
185
224
// Error if there are null bytes within the url
186
225
// https://github.com/tjtelan/git-url-parse-rs/issues/16
187
226
if input. contains ( '\0' ) {
@@ -190,19 +229,26 @@ impl<'url> GitUrl<'url> {
190
229
191
230
let ( _input, url_spec_parser) = UrlSpecParser :: parse ( input) . finish ( ) . unwrap_or_default ( ) ;
192
231
193
- let mut scheme = url_spec_parser. scheme ( ) ;
232
+ let scheme = url_spec_parser. scheme ( ) ;
194
233
let user = url_spec_parser. hier_part ( ) . authority ( ) . userinfo ( ) . user ( ) ;
195
234
let password = url_spec_parser. hier_part ( ) . authority ( ) . userinfo ( ) . token ( ) ;
196
235
let host = url_spec_parser. hier_part ( ) . authority ( ) . host ( ) ;
197
236
let port = url_spec_parser. hier_part ( ) . authority ( ) . port ( ) ;
198
- let mut path = url_spec_parser. hier_part ( ) . path ( ) ;
237
+ let path = url_spec_parser. hier_part ( ) . path ( ) ;
238
+
239
+ git_url_result. set_scheme ( scheme. clone ( ) ) ;
240
+ git_url_result. set_user ( user. clone ( ) ) ;
241
+ git_url_result. set_password ( password. clone ( ) ) ;
242
+ git_url_result. set_host ( host. clone ( ) ) ;
243
+ git_url_result. set_port ( * port) ;
244
+ git_url_result. set_path ( path. clone ( ) ) ;
199
245
200
246
// We will respect whether scheme was initially set
201
247
let print_scheme = scheme. is_some ( ) ;
202
248
203
249
// Take a moment to identify the type of url we have
204
250
// We use the GitUrlParseHint to validate or adjust formatting path, if necessary
205
- let hint = if let Some ( scheme) = scheme {
251
+ let hint = if let Some ( scheme) = scheme. as_ref ( ) {
206
252
if scheme. contains ( "ssh" ) {
207
253
GitUrlParseHint :: Sshlike
208
254
} else {
@@ -232,36 +278,20 @@ impl<'url> GitUrl<'url> {
232
278
// If we found an ssh url, we should adjust the path.
233
279
// Skip the first character
234
280
if hint == GitUrlParseHint :: Sshlike {
235
- if let Some ( scheme) = scheme. as_mut ( ) {
236
- * scheme = "ssh" ;
237
- } else {
238
- scheme = Some ( "ssh" )
239
- }
240
- path = & path[ 1 ..] ;
281
+ git_url_result. set_scheme ( Some ( "ssh" . to_string ( ) ) ) ;
282
+ git_url_result. set_path ( path[ 1 ..] . to_string ( ) ) ;
241
283
}
242
284
243
285
if hint == GitUrlParseHint :: Filelike {
244
- if let Some ( scheme) = scheme. as_mut ( ) {
245
- * scheme = "file" ;
246
- } else {
247
- scheme = Some ( "file" )
248
- }
286
+ git_url_result. set_scheme ( Some ( "file" . to_string ( ) ) ) ;
249
287
}
250
288
251
- let git_url = GitUrl {
252
- scheme,
253
- user,
254
- password,
255
- host,
256
- port,
257
- path,
258
- print_scheme,
259
- hint,
260
- } ;
289
+ git_url_result. set_print_scheme ( print_scheme) ;
290
+ git_url_result. set_hint ( hint) ;
261
291
262
- git_url . is_valid ( ) ?;
292
+ git_url_result . is_valid ( ) ?;
263
293
264
- Ok ( git_url )
294
+ Ok ( git_url_result )
265
295
}
266
296
267
297
/// ```
@@ -278,7 +308,7 @@ impl<'url> GitUrl<'url> {
278
308
/// # }
279
309
pub fn provider_info < T > ( & self ) -> Result < T , GitUrlParseError >
280
310
where
281
- T : provider:: GitProvider < GitUrl < ' url > , GitUrlParseError > ,
311
+ T : provider:: GitProvider < GitUrl , GitUrlParseError > ,
282
312
{
283
313
T :: from_git_url ( self )
284
314
}
0 commit comments