@@ -14,7 +14,7 @@ use core::str;
1414use std:: fmt;
1515use url:: Url ;
1616
17- use getset:: { CloneGetters , CopyGetters , Setters } ;
17+ use getset:: { CopyGetters , Getters , Setters } ;
1818#[ cfg( feature = "log" ) ]
1919use log:: debug;
2020use nom:: Finish ;
@@ -42,45 +42,82 @@ pub(crate) enum GitUrlParseHint {
4242/// GitUrl is an input url used by git.
4343/// Parsing of the url inspired by rfc3986, but does not strictly cover the spec
4444/// 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 ) ]
4646#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
47- pub struct GitUrl < ' url > {
47+ #[ getset( set = "pub(crate)" ) ]
48+ pub struct GitUrl {
4849 /// scheme name (i.e. `scheme://`)
49- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
50- scheme : Option < & ' url str > ,
50+ scheme : Option < String > ,
5151 /// user name userinfo
52- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
53- user : Option < & ' url str > ,
52+ user : Option < String > ,
5453 /// 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 > ,
5755 /// The hostname or IP of the repo host
58- #[ getset( get_copy = "pub" ) ]
59- host : Option < & ' url str > ,
56+ host : Option < String > ,
6057 /// The port number of the repo host, if specified
6158 #[ getset( get_copy = "pub" ) ]
6259 port : Option < u16 > ,
6360 /// File or network path to repo
64- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
65- path : & ' url str ,
61+ path : String ,
6662 /// If we should print `scheme://` from input or derived during parsing
67- #[ getset( get_copy = "pub" , set = "pub(crate)" ) ]
63+ #[ getset( get_copy = "pub" ) ]
6864 print_scheme : bool ,
6965 /// Pattern style of url derived during parsing
70- #[ getset( get_copy = "pub(crate) " ) ]
66+ #[ getset( get_copy = "pub" ) ]
7167 hint : GitUrlParseHint ,
7268}
7369
7470/// Build the printable GitUrl from its components
75- impl fmt:: Display for GitUrl < ' _ > {
71+ impl fmt:: Display for GitUrl {
7672 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
7773 let git_url_str = self . display ( ) ;
7874
7975 write ! ( f, "{git_url_str}" , )
8076 }
8177}
8278
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+
84121 /// Wrapper function for the default output mode via [`Display`](std::fmt::Display) trait
85122 fn display ( & self ) -> String {
86123 self . build_string ( false )
@@ -142,7 +179,7 @@ impl<'url> GitUrl<'url> {
142179}
143180
144181#[ cfg( feature = "url" ) ]
145- impl < ' url > TryFrom < & GitUrl < ' url > > for Url {
182+ impl TryFrom < & GitUrl > for Url {
146183 type Error = url:: ParseError ;
147184 fn try_from ( value : & GitUrl ) -> Result < Self , Self :: Error > {
148185 // 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 {
151188}
152189
153190#[ cfg( feature = "url" ) ]
154- impl < ' url > TryFrom < GitUrl < ' url > > for Url {
191+ impl TryFrom < GitUrl > for Url {
155192 type Error = url:: ParseError ;
156193 fn try_from ( value : GitUrl ) -> Result < Self , Self :: Error > {
157194 // Since we don't fully implement any spec, we'll rely on the url crate
158195 Url :: parse ( & value. url_compat_display ( ) )
159196 }
160197}
161198
162- impl < ' url > GitUrl < ' url > {
199+ impl GitUrl {
163200 /// Returns `GitUrl` after removing all user info values
164201 pub fn trim_auth ( & self ) -> GitUrl {
165202 let mut new_giturl = self . clone ( ) ;
@@ -181,7 +218,9 @@ impl<'url> GitUrl<'url> {
181218 /// # Ok(())
182219 /// # }
183220 /// ```
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+
185224 // Error if there are null bytes within the url
186225 // https://github.com/tjtelan/git-url-parse-rs/issues/16
187226 if input. contains ( '\0' ) {
@@ -190,19 +229,26 @@ impl<'url> GitUrl<'url> {
190229
191230 let ( _input, url_spec_parser) = UrlSpecParser :: parse ( input) . finish ( ) . unwrap_or_default ( ) ;
192231
193- let mut scheme = url_spec_parser. scheme ( ) ;
232+ let scheme = url_spec_parser. scheme ( ) ;
194233 let user = url_spec_parser. hier_part ( ) . authority ( ) . userinfo ( ) . user ( ) ;
195234 let password = url_spec_parser. hier_part ( ) . authority ( ) . userinfo ( ) . token ( ) ;
196235 let host = url_spec_parser. hier_part ( ) . authority ( ) . host ( ) ;
197236 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 ( ) ) ;
199245
200246 // We will respect whether scheme was initially set
201247 let print_scheme = scheme. is_some ( ) ;
202248
203249 // Take a moment to identify the type of url we have
204250 // 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 ( ) {
206252 if scheme. contains ( "ssh" ) {
207253 GitUrlParseHint :: Sshlike
208254 } else {
@@ -232,36 +278,20 @@ impl<'url> GitUrl<'url> {
232278 // If we found an ssh url, we should adjust the path.
233279 // Skip the first character
234280 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 ( ) ) ;
241283 }
242284
243285 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 ( ) ) ) ;
249287 }
250288
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) ;
261291
262- git_url . is_valid ( ) ?;
292+ git_url_result . is_valid ( ) ?;
263293
264- Ok ( git_url )
294+ Ok ( git_url_result )
265295 }
266296
267297 /// ```
@@ -278,7 +308,7 @@ impl<'url> GitUrl<'url> {
278308 /// # }
279309 pub fn provider_info < T > ( & self ) -> Result < T , GitUrlParseError >
280310 where
281- T : provider:: GitProvider < GitUrl < ' url > , GitUrlParseError > ,
311+ T : provider:: GitProvider < GitUrl , GitUrlParseError > ,
282312 {
283313 T :: from_git_url ( self )
284314 }
0 commit comments