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)]
31pub enum IssueRef {
32    GitHub {
33        owner: String,
34        repo: String,
35        number: u64,
36    },
37    /// A Linear issue identified by its UUID, paired with the GitHub repo that
38    /// hosts the code for that project.
39    Linear {
40        owner: String,
41        repo: String,
42        id: String,
43    },
44    /// A local Centy issue — the repository itself is the source, no remote clone needed.
45    Local {
46        project_path: PathBuf,
47        display_number: u32,
48    },
49}
50
51impl IssueRef {
52    /// Directory name used inside the bare clone for this worktree.
53    pub fn workspace_dir_name(&self) -> String {
54        match self {
55            Self::GitHub { number, .. } => format!("issue-{number}"),
56            Self::Linear { id, .. } => format!("linear-{id}"),
57            Self::Local { display_number, .. } => format!("issue-{display_number}"),
58        }
59    }
60
61    /// Git branch name for this issue worktree.
62    pub fn branch_name(&self) -> String {
63        self.workspace_dir_name()
64    }
65
66    /// HTTPS clone URL for the repository.
67    ///
68    /// # Panics
69    ///
70    /// Always panics for `IssueRef::Local` — local repos are never cloned.
71    pub fn clone_url(&self) -> String {
72        match self {
73            Self::GitHub { owner, repo, .. } | Self::Linear { owner, repo, .. } => {
74                format!("https://github.com/{owner}/{repo}.git")
75            }
76            Self::Local { .. } => {
77                unreachable!("clone_url is never called for IssueRef::Local")
78            }
79        }
80    }
81}