Skip to content

Commit c4dc079

Browse files
committed
Implement TryFrom<GitUrl> for url::Url
GitUrl::url_compat_display() is currently private, but it would be very useful to have this functionality - in my case, normalizing an SSH style URL is fine, especially because I do not want to bother with handling the 'url lifetime of GitUrl in my wrapper enum. This change implements fallible conversion to url::Url for GitUrl and &GitUrl via url_compat_display(). Longer term it might be wise to re-visit the use of a lifetime for the purpose of re-using slices of the input string - the url::Url crate does not bother with such micro-optimizations either, presumably for good reasons. Obviously, to use a GitUrl as a url::Url, the conversion to url::Url still has to happen twice (because GitUrl::parse() incurs the conversion via GitUrl::is_valid()), but that can be optimized in a separate change (e.g. via a new GitUrl::parse_to_url(), or by removing the conversion from is_valid() altogether, leaving it to the caller to attempt the conversion).
1 parent de0e16f commit c4dc079

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/types/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub use error::GitUrlParseError;
1212

1313
use core::str;
1414
use std::fmt;
15+
use url::Url;
1516

1617
use getset::{CloneGetters, CopyGetters, Setters};
1718
#[cfg(feature = "log")]
@@ -140,6 +141,24 @@ impl<'url> GitUrl<'url> {
140141
}
141142
}
142143

144+
#[cfg(feature = "url")]
145+
impl<'url> TryFrom<&GitUrl<'url>> for Url {
146+
type Error = url::ParseError;
147+
fn try_from(value: &GitUrl) -> Result<Self, Self::Error> {
148+
// Since we don't fully implement any spec, we'll rely on the url crate
149+
Url::parse(&value.url_compat_display())
150+
}
151+
}
152+
153+
#[cfg(feature = "url")]
154+
impl<'url> TryFrom<GitUrl<'url>> for Url {
155+
type Error = url::ParseError;
156+
fn try_from(value: GitUrl) -> Result<Self, Self::Error> {
157+
// Since we don't fully implement any spec, we'll rely on the url crate
158+
Url::parse(&value.url_compat_display())
159+
}
160+
}
161+
143162
impl<'url> GitUrl<'url> {
144163
/// Returns `GitUrl` after removing all user info values
145164
pub fn trim_auth(&self) -> GitUrl {
@@ -325,7 +344,7 @@ impl<'url> GitUrl<'url> {
325344
#[cfg(feature = "url")]
326345
{
327346
// Since we don't fully implement any spec, we'll rely on the url crate
328-
let _u = url::Url::parse(&self.url_compat_display())?;
347+
let _u: Url = self.try_into()?;
329348
}
330349

331350
Ok(())

0 commit comments

Comments
 (0)