1use anyhow::Result;
2use clap_complete::engine::ArgValueCompleter;
3
4use crate::cli::parse_distance;
5use crate::commands::Run;
6use crate::completions;
7
8#[derive(Debug, clap::Args)]
10pub struct Up {
11 #[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 #[arg(long)]
23 from_path: bool,
24}
25
26#[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}