Skip to content

Commit 28a2988

Browse files
authored
feat: Implement TryFrom<GitUrl> for url::Url (#66)
`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 `GitUrl::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 `GitUrl::is_valid()` altogether, leaving it to the caller to attempt the conversion.
1 parent de0e16f commit 28a2988

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)