Skip to main content

worktree_io/issue/
mod.rs

1use std::path::PathBuf;
2
3mod parse;
4mod paths;
5
6#[cfg(test)]
7mod tests;
8
9#[cfg(test)]
10mod linear_tests;
11
12#[cfg(test)]
13mod uuid_tests;
14
15#[cfg(test)]
16mod parse_tests;
17
18#[cfg(test)]
19mod local_tests;
20
21/// Options extracted from a `worktree://` deep link.
22#[derive(Debug, Clone, Default)]
23pub struct DeepLinkOptions {
24    /// Editor override from the `editor` query param. May be a symbolic name
25    /// (`cursor`, `code`, `zed`, `nvim`, etc.) or a raw percent-decoded command.
26    pub editor: Option<String>,
27}
28
29/// A reference to an issue that identifies a workspace.
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub enum IssueRef {
32    /// A GitHub issue identified by owner, repo, and number.
33    GitHub {
34        /// GitHub organization or user name.
35        owner: String,
36        /// Repository name.
37        repo: String,
38        /// Issue number.
39        number: u64,
40    },
41    /// A Linear issue identified by its UUID, paired with the GitHub repo that
42    /// hosts the code for that project.
43    Linear {
44        /// GitHub organization or user name that hosts the code.
45        owner: String,
46        /// Repository name.
47        repo: String,
48        /// Linear issue UUID.
49        id: String,
50    },
51    /// A local Centy issue — the repository itself is the source, no remote clone needed.
52    Local {
53        /// Absolute path to the local project repository.
54        project_path: PathBuf,
55        /// Human-readable issue number shown in the branch name.
56        display_number: u32,
57    },
58}
59
60impl IssueRef {
61    /// Directory name used inside the bare clone for this worktree.
62    #[must_use]
63    pub fn workspace_dir_name(&self) -> String {
64        match self {
65            Self::GitHub { number, .. } => format!("issue-{number}"),
66            Self::Linear { id, .. } => format!("linear-{id}"),
67            Self::Local { display_number, .. } => format!("issue-{display_number}"),
68        }
69    }
70
71    /// Git branch name for this issue worktree.
72    #[must_use]
73    pub fn branch_name(&self) -> String {
74        self.workspace_dir_name()
75    }
76
77    /// HTTPS clone URL for the repository.
78    ///
79    /// # Panics
80    ///
81    /// Always panics for `IssueRef::Local` — local repos are never cloned.
82    #[must_use]
83    pub fn clone_url(&self) -> String {
84        match self {
85            Self::GitHub { owner, repo, .. } | Self::Linear { owner, repo, .. } => {
86                format!("https://github.com/{owner}/{repo}.git")
87            }
88            Self::Local { .. } => {
89                unreachable!("clone_url is never called for IssueRef::Local")
90            }
91        }
92    }
93}