Skip to main content

worktree_io/issue/parse/
mod.rs

1mod azure;
2mod github;
3mod shorthand;
4mod worktree_url;
5
6use anyhow::{bail, Result};
7
8use super::{DeepLinkOptions, IssueRef};
9
10impl IssueRef {
11    /// Parse any of the supported input formats:
12    /// - `https://github.com/owner/repo/issues/42`
13    /// - `worktree://open?owner=X&repo=Y&issue=42`
14    /// - `worktree://open?url=<encoded-github-url>`
15    /// - `worktree://open?owner=X&repo=Y&linear_id=<uuid>`
16    /// - `owner/repo#42`
17    /// - `owner/repo@<linear-uuid>`
18    ///
19    /// # Errors
20    ///
21    /// Returns an error if `s` does not match any supported format or if the
22    /// extracted values (e.g. issue number) are invalid.
23    pub fn parse(s: &str) -> Result<Self> {
24        let s = s.trim();
25
26        if s.starts_with("worktree://") {
27            let (issue, _opts) = worktree_url::parse_worktree_url(s)?;
28            return Ok(issue);
29        }
30
31        if s.starts_with("https://github.com") || s.starts_with("http://github.com") {
32            return github::parse_github_url(s);
33        }
34
35        if s.starts_with("https://dev.azure.com") || s.starts_with("http://dev.azure.com") {
36            return azure::parse_azure_devops_url(s);
37        }
38
39        if let Some(result) = shorthand::try_parse_shorthand(s) {
40            return result;
41        }
42
43        bail!(
44            "Could not parse issue reference: {s:?}\n\
45             Supported formats:\n\
46             - https://github.com/owner/repo/issues/42\n\
47             - https://dev.azure.com/org/project/_workitems/edit/42\n\
48             - worktree://open?owner=owner&repo=repo&issue=42\n\
49             - worktree://open?owner=owner&repo=repo&linear_id=<uuid>\n\
50             - worktree://open?org=org&project=project&repo=repo&work_item_id=42\n\
51             - owner/repo#42\n\
52             - owner/repo@<linear-uuid>\n\
53             - org/project/repo!42"
54        )
55    }
56
57    /// Like [`parse`] but also returns any [`DeepLinkOptions`] embedded in a
58    /// `worktree://` URL (e.g. the `editor` query param).
59    ///
60    /// # Errors
61    ///
62    /// Returns an error if `s` cannot be parsed as a valid issue reference.
63    pub fn parse_with_options(s: &str) -> Result<(Self, DeepLinkOptions)> {
64        let s = s.trim();
65        if s.starts_with("worktree://") {
66            return worktree_url::parse_worktree_url(s);
67        }
68        Ok((Self::parse(s)?, DeepLinkOptions::default()))
69    }
70}