Initial commit: git-issue-commit CLI tool
This commit is contained in:
117
src/parser/url.rs
Normal file
117
src/parser/url.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Provider {
|
||||
GitHub,
|
||||
GitLab,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParsedIssueUrl {
|
||||
pub provider: Provider,
|
||||
pub owner: String,
|
||||
pub repo: String,
|
||||
pub issue_number: u64,
|
||||
pub is_pull_request: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum UrlParseError {
|
||||
#[error("Invalid URL format")]
|
||||
InvalidFormat,
|
||||
#[error("Unsupported provider")]
|
||||
UnsupportedProvider,
|
||||
#[error("Missing issue number")]
|
||||
MissingIssueNumber,
|
||||
}
|
||||
|
||||
pub fn parse_issue_url(url: &str) -> Result<ParsedIssueUrl, UrlParseError> {
|
||||
if let Some(github_url) = parse_github_url(url) {
|
||||
return Ok(github_url);
|
||||
}
|
||||
if let Some(gitlab_url) = parse_gitlab_url(url) {
|
||||
return Ok(gitlab_url);
|
||||
}
|
||||
Err(UrlParseError::InvalidFormat)
|
||||
}
|
||||
|
||||
fn parse_github_url(url: &str) -> Option<ParsedIssueUrl> {
|
||||
let re = regex::Regex::new(r"github\.com/([^/]+)/([^/]+)/(?:issues|pull)/(\d+)").expect("Invalid regex pattern for GitHub URLs");
|
||||
let caps = re.captures(url)?;
|
||||
|
||||
let owner = caps.get(1)?.as_str().to_string();
|
||||
let repo = caps.get(2)?.as_str().to_string();
|
||||
let issue_number = caps.get(3)?.as_str().parse().ok()?;
|
||||
let is_pull_request = url.contains("/pull/");
|
||||
|
||||
Some(ParsedIssueUrl {
|
||||
provider: Provider::GitHub,
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
is_pull_request,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_gitlab_url(url: &str) -> Option<ParsedIssueUrl> {
|
||||
let re = regex::Regex::new(r"gitlab\.com/([^/]+)/([^/]+)/-/issues/(\d+)").expect("Invalid regex pattern for GitLab URLs");
|
||||
let caps = re.captures(url)?;
|
||||
|
||||
let owner = caps.get(1)?.as_str().to_string();
|
||||
let repo = caps.get(2)?.as_str().to_string();
|
||||
let issue_number = caps.get(3)?.as_str().parse().ok()?;
|
||||
let is_pull_request = url.contains("/merge_requests");
|
||||
|
||||
Some(ParsedIssueUrl {
|
||||
provider: Provider::GitLab,
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
is_pull_request,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_github_issue_url() {
|
||||
let url = "https://github.com/owner/repo/issues/123";
|
||||
let parsed = parse_issue_url(url).unwrap();
|
||||
assert_eq!(parsed.provider, Provider::GitHub);
|
||||
assert_eq!(parsed.owner, "owner");
|
||||
assert_eq!(parsed.repo, "repo");
|
||||
assert_eq!(parsed.issue_number, 123);
|
||||
assert!(!parsed.is_pull_request);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_github_pr_url() {
|
||||
let url = "https://github.com/owner/repo/pull/456";
|
||||
let parsed = parse_issue_url(url).unwrap();
|
||||
assert_eq!(parsed.provider, Provider::GitHub);
|
||||
assert_eq!(parsed.owner, "owner");
|
||||
assert_eq!(parsed.repo, "repo");
|
||||
assert_eq!(parsed.issue_number, 456);
|
||||
assert!(parsed.is_pull_request);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_gitlab_issue_url() {
|
||||
let url = "https://gitlab.com/owner/repo/-/issues/789";
|
||||
let parsed = parse_issue_url(url).unwrap();
|
||||
assert_eq!(parsed.provider, Provider::GitLab);
|
||||
assert_eq!(parsed.owner, "owner");
|
||||
assert_eq!(parsed.repo, "repo");
|
||||
assert_eq!(parsed.issue_number, 789);
|
||||
assert!(!parsed.is_pull_request);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_invalid_url() {
|
||||
let result = parse_issue_url("not-a-valid-url");
|
||||
assert!(result.is_err());
|
||||
assert_eq!(result.unwrap_err(), UrlParseError::InvalidFormat);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user