diff options
| author | Teddy Wing | 2020-08-01 21:21:53 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2020-08-01 21:21:53 +0200 | 
| commit | e0f75bb732e2f1c66a9121142399bcd1d604a4f3 (patch) | |
| tree | c891e4a47b1d4e766de396e3337c5bd682aa0422 /src | |
| parent | d64951ef8fc55733d6b87a0ea6f1a16186eba3d2 (diff) | |
| download | git-suggestion-e0f75bb732e2f1c66a9121142399bcd1d604a4f3.tar.bz2 | |
OwnerRepo: Parse from SSH-style paths
Remotes can be HTTP URLs or use SSH/SCP-style paths like:
    git@github.com/teddywing/github-suggestion.git
We need to handle both regular URLs and the above style, which isn't
parseable by the 'url' crate.
Add a custom parsing function to get the owner and repo from this
format.
When trying to parse `OwnerRepo` from a string, first try to parse it as
a URL. If that fails with a `RelativeUrlWithoutBase` error, assume it's
the other style of reference.
Diffstat (limited to 'src')
| -rw-r--r-- | src/owner_repo.rs | 28 | 
1 files changed, 27 insertions, 1 deletions
| diff --git a/src/owner_repo.rs b/src/owner_repo.rs index 67572ef..a94c67f 100644 --- a/src/owner_repo.rs +++ b/src/owner_repo.rs @@ -41,7 +41,12 @@ impl FromStr for OwnerRepo {      type Err = OwnerRepoError;      fn from_str(s: &str) -> Result<Self, Self::Err> { -        let url = Url::parse(s)?; +        let url = match Url::parse(s) { +            Err(url::ParseError::RelativeUrlWithoutBase) => +                return OwnerRepo::from_ssh(s), + +            r => r, +        }?;          let path = url.path_segments()              .ok_or(OwnerRepoError::NoPath)?              .collect::<Vec<_>>(); @@ -74,4 +79,25 @@ impl OwnerRepo {          Ok(url.parse()?)      } + +    pub fn from_ssh(ssh: &str) -> Result<Self, OwnerRepoError> { +        let address_path: Vec<_> = ssh.splitn(2, ':').collect(); +        let path = address_path.get(1) +            .ok_or(OwnerRepoError::NoOwnerRepo)?; + +        let path = path +            .strip_suffix(".git") +            .unwrap_or(path); + +        let segments: Vec<_> = path.split('/').collect(); + +        if segments.len() < 2 { +            return Err(OwnerRepoError::NoOwnerRepo); +        } + +        Ok(OwnerRepo { +            owner: segments[0].to_owned(), +            repo: segments[1].to_owned(), +        }) +    }  } | 
