use anyhow::{bail, Context, Result};
use url::Url;
use crate::issue::IssueRef;
pub(super) fn resolve_worktree_params(
org: Option<String>,
project: Option<String>,
repo: Option<String>,
id: u64,
) -> Result<IssueRef> {
let org = org.context("Missing 'org' query param")?;
let project = project.context("Missing 'project' query param")?;
let repo = repo.unwrap_or_else(|| project.clone());
Ok(IssueRef::AzureDevOps {
org,
project,
repo,
id,
})
}
pub(super) fn parse_azure_devops_url(s: &str) -> Result<IssueRef> {
let url = Url::parse(s).with_context(|| format!("Invalid URL: {s}"))?;
let segments: Vec<&str> = url
.path_segments()
.context("URL has no path")?
.filter(|s| !s.is_empty())
.collect();
if segments.len() < 5 || segments[2] != "_workitems" || segments[3] != "edit" {
bail!(
"Expected Azure DevOps work item URL like \
https://dev.azure.com/org/project/_workitems/edit/42, got: {s}"
);
}
let org = segments[0].to_string();
let project = segments[1].to_string();
let id = segments[4]
.parse::<u64>()
.with_context(|| format!("Invalid work item ID in URL: {}", segments[4]))?;
Ok(IssueRef::AzureDevOps {
repo: project.clone(),
org,
project,
id,
})
}