diff options
author | Teddy Wing | 2020-08-01 14:51:49 +0200 |
---|---|---|
committer | Teddy Wing | 2020-08-01 14:51:49 +0200 |
commit | b218abebdf8a0aed73bfe6f61ab22e51a0f2f43c (patch) | |
tree | 8b24a1c821696dfc790b258f6c1a9355313878fa /github-suggestion-cli/src | |
parent | eb74fee6be6876b86c97cdea0205ec970152358e (diff) | |
download | git-suggestion-b218abebdf8a0aed73bfe6f61ab22e51a0f2f43c.tar.bz2 |
Move `github-suggestion-config` to `github-suggestion-cli`
Going to use this for more cli-oriented code, so that the binaries can
share more logic.
Diffstat (limited to 'github-suggestion-cli/src')
-rw-r--r-- | github-suggestion-cli/src/lib.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/github-suggestion-cli/src/lib.rs b/github-suggestion-cli/src/lib.rs new file mode 100644 index 0000000..c0d97a2 --- /dev/null +++ b/github-suggestion-cli/src/lib.rs @@ -0,0 +1,75 @@ +use std::str::FromStr; + +use git2::Repository; +use thiserror::Error; +use url; +use url::Url; + + +#[derive(Debug, Error)] +pub enum Error { + #[error(transparent)] + Git(#[from] git2::Error), + + #[error(transparent)] + OwnerRepo(#[from] OwnerRepoError), + + #[error("Unable to find remote '{0}'")] + NoRemote(String), +} + +#[derive(Debug, Error)] +pub enum OwnerRepoError { + #[error("Unable to parse URL")] + Url(#[from] url::ParseError), + + #[error("URL has no path")] + NoPath, + + #[error("Unable to parse owner or repo")] + NoOwnerRepo, +} + + +#[derive(Debug)] +pub struct OwnerRepo { + pub owner: String, + pub repo: String, +} + +impl FromStr for OwnerRepo { + type Err = OwnerRepoError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let url = Url::parse(s)?; + let path = url.path_segments() + .ok_or(OwnerRepoError::NoPath)? + .collect::<Vec<_>>(); + + if path.len() < 2 { + return Err(OwnerRepoError::NoOwnerRepo); + } + + Ok(OwnerRepo { + owner: path[0].to_owned(), + repo: path[1].to_owned(), + }) + } +} + +pub fn identifier_for_remote( + remote_name: Option<&str>, +) -> Result<OwnerRepo, Error> { + let repo = Repository::open(".")?; + + let remote_name = match remote_name { + Some(r) => r, + None => "origin", + }; + + let remote = repo.find_remote(remote_name)?; + let url = remote.url() + .ok_or_else(|| Error::NoRemote(remote_name.to_owned()))?; + + Ok(url.parse()?) +} |