Skip to main content

git_stk/commands/
up.rs

1use anyhow::Result;
2use clap_complete::engine::ArgValueCompleter;
3
4use crate::cli::parse_distance;
5use crate::commands::Run;
6use crate::completions;
7
8/// Move up the stack: check out a child of the current branch.
9#[derive(Debug, clap::Args)]
10pub struct Up {
11    /// A child branch to check out, or how many branches to move up.
12    #[arg(
13        value_name = "BRANCH|COUNT",
14        value_parser = parse_target,
15        allow_negative_numbers = true,
16        add = ArgValueCompleter::new(completions::child_branch_candidates)
17    )]
18    target: Option<Target>,
19    /// Print the destination directory instead of announcing the switch, so
20    /// `cd "$(git stk up --from-path)"` follows the branch - including into another
21    /// worktree, which cannot be checked out here.
22    #[arg(long)]
23    from_path: bool,
24}
25
26/// Where to go, or how far: a number is read as a distance, so a branch whose
27/// name is only digits has to be reached by name from elsewhere.
28#[derive(Debug, Clone)]
29enum Target {
30    Branch(String),
31    Distance(usize),
32}
33
34fn parse_target(value: &str) -> Result<Target, String> {
35    if value.parse::<i64>().is_ok() {
36        return parse_distance(value).map(Target::Distance);
37    }
38    Ok(Target::Branch(value.to_owned()))
39}
40
41impl Run for Up {
42    fn run(self) -> Result<()> {
43        let output = self.nav_output();
44        match self.target {
45            Some(Target::Branch(branch)) => crate::stack::checkout_child(Some(&branch), 1, output),
46            Some(Target::Distance(distance)) => {
47                crate::stack::checkout_child(None, distance, output)
48            }
49            None => crate::stack::checkout_child(None, 1, output),
50        }
51    }
52}
53
54impl Up {
55    fn nav_output(&self) -> crate::stack::NavOutput {
56        if self.from_path {
57            crate::stack::NavOutput::Path
58        } else {
59            crate::stack::NavOutput::Announce
60        }
61    }
62}