Skip to main content

git_spawn/command/
switch.rs

1//! `git switch` — switch branches (modern successor to `checkout`).
2
3use crate::command::{CommandExecutor, CommandOutput, GitCommand};
4use crate::error::Result;
5use async_trait::async_trait;
6
7/// Builder for `git switch`.
8#[derive(Debug, Clone, Default)]
9pub struct SwitchCommand {
10    /// Shared executor.
11    pub executor: CommandExecutor,
12    /// Target branch.
13    pub target: Option<String>,
14    /// `-c` create.
15    pub create: Option<String>,
16    /// `-C` force create.
17    pub force_create: Option<String>,
18    /// `--detach`.
19    pub detach: bool,
20    /// `--discard-changes`.
21    pub discard_changes: bool,
22    /// `--track`.
23    pub track: bool,
24    /// `--no-track`.
25    pub no_track: bool,
26    /// `--orphan`.
27    pub orphan: Option<String>,
28}
29
30impl SwitchCommand {
31    /// New `switch` command.
32    #[must_use]
33    pub fn new() -> Self {
34        Self::default()
35    }
36
37    /// Target branch.
38    pub fn target(&mut self, t: impl Into<String>) -> &mut Self {
39        self.target = Some(t.into());
40        self
41    }
42
43    /// Create a branch (`-c`).
44    pub fn create(&mut self, name: impl Into<String>) -> &mut Self {
45        self.create = Some(name.into());
46        self
47    }
48
49    /// Force-create (`-C`).
50    pub fn force_create(&mut self, name: impl Into<String>) -> &mut Self {
51        self.force_create = Some(name.into());
52        self
53    }
54
55    /// Detach HEAD.
56    pub fn detach(&mut self) -> &mut Self {
57        self.detach = true;
58        self
59    }
60
61    /// Discard local changes.
62    pub fn discard_changes(&mut self) -> &mut Self {
63        self.discard_changes = true;
64        self
65    }
66
67    /// `--track`.
68    pub fn track(&mut self) -> &mut Self {
69        self.track = true;
70        self
71    }
72
73    /// `--no-track`.
74    pub fn no_track(&mut self) -> &mut Self {
75        self.no_track = true;
76        self
77    }
78
79    /// Orphan branch.
80    pub fn orphan(&mut self, name: impl Into<String>) -> &mut Self {
81        self.orphan = Some(name.into());
82        self
83    }
84}
85
86#[async_trait]
87impl GitCommand for SwitchCommand {
88    type Output = CommandOutput;
89    fn get_executor(&self) -> &CommandExecutor {
90        &self.executor
91    }
92    fn get_executor_mut(&mut self) -> &mut CommandExecutor {
93        &mut self.executor
94    }
95    fn build_command_args(&self) -> Vec<String> {
96        let mut args = vec!["switch".to_string()];
97        if self.detach {
98            args.push("--detach".into());
99        }
100        if self.discard_changes {
101            args.push("--discard-changes".into());
102        }
103        if self.track {
104            args.push("--track".into());
105        }
106        if self.no_track {
107            args.push("--no-track".into());
108        }
109        if let Some(o) = &self.orphan {
110            args.push("--orphan".into());
111            args.push(o.clone());
112        }
113        if let Some(b) = &self.create {
114            args.push("-c".into());
115            args.push(b.clone());
116        }
117        if let Some(b) = &self.force_create {
118            args.push("-C".into());
119            args.push(b.clone());
120        }
121        if let Some(t) = &self.target {
122            args.push(t.clone());
123        }
124        args
125    }
126    async fn execute(&self) -> Result<CommandOutput> {
127        self.execute_raw().await
128    }
129}