Skip to content

Commit f6be7c4

Browse files
committed
Remove lifetime from GitUrl
Fixes #69
1 parent a67c7fa commit f6be7c4

File tree

5 files changed

+197
-124
lines changed

5 files changed

+197
-124
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
//! #[derive(Debug, Clone, PartialEq, Eq)]
5151
//! struct CustomProvider;
5252
//!
53-
//! impl GitProvider<GitUrl<'_>, GitUrlParseError> for CustomProvider {
53+
//! impl GitProvider<GitUrl, GitUrlParseError> for CustomProvider {
5454
//! fn from_git_url(_url: &GitUrl) -> Result<Self, GitUrlParseError> {
5555
//! // Your custom provider parsing here
5656
//! Ok(Self)

src/types/mod.rs

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use core::str;
1414
use std::fmt;
1515
use url::Url;
1616

17-
use getset::{CloneGetters, CopyGetters, Setters};
17+
use getset::{CopyGetters, Getters, Setters};
1818
#[cfg(feature = "log")]
1919
use log::debug;
2020
use 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

Comments
 (0)