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