git_spawn/command/
symbolic_ref.rs1use crate::command::{CommandExecutor, GitCommand};
4use crate::error::{Error, Result};
5use async_trait::async_trait;
6
7#[derive(Debug, Clone)]
9pub enum SymbolicRefAction {
10 Read {
12 name: String,
14 short: bool,
16 },
17 Set {
19 name: String,
21 target: String,
23 reason: Option<String>,
25 },
26 Delete {
28 name: String,
30 quiet: bool,
32 },
33}
34
35#[derive(Debug, Clone)]
37pub struct SymbolicRefCommand {
38 pub executor: CommandExecutor,
40 pub action: SymbolicRefAction,
42}
43
44impl SymbolicRefCommand {
45 pub fn read(name: impl Into<String>) -> Self {
47 Self {
48 executor: CommandExecutor::default(),
49 action: SymbolicRefAction::Read {
50 name: name.into(),
51 short: false,
52 },
53 }
54 }
55
56 pub fn short(&mut self) -> &mut Self {
58 if let SymbolicRefAction::Read { short, .. } = &mut self.action {
59 *short = true;
60 }
61 self
62 }
63
64 pub fn set(name: impl Into<String>, target: impl Into<String>) -> Self {
66 Self {
67 executor: CommandExecutor::default(),
68 action: SymbolicRefAction::Set {
69 name: name.into(),
70 target: target.into(),
71 reason: None,
72 },
73 }
74 }
75
76 pub fn reason(&mut self, r: impl Into<String>) -> &mut Self {
78 if let SymbolicRefAction::Set { reason, .. } = &mut self.action {
79 *reason = Some(r.into());
80 }
81 self
82 }
83
84 pub fn delete(name: impl Into<String>) -> Self {
86 Self {
87 executor: CommandExecutor::default(),
88 action: SymbolicRefAction::Delete {
89 name: name.into(),
90 quiet: false,
91 },
92 }
93 }
94
95 pub fn quiet(&mut self) -> &mut Self {
97 if let SymbolicRefAction::Delete { quiet, .. } = &mut self.action {
98 *quiet = true;
99 }
100 self
101 }
102}
103
104#[async_trait]
105impl GitCommand for SymbolicRefCommand {
106 type Output = String;
108
109 fn get_executor(&self) -> &CommandExecutor {
110 &self.executor
111 }
112
113 fn get_executor_mut(&mut self) -> &mut CommandExecutor {
114 &mut self.executor
115 }
116
117 fn build_command_args(&self) -> Vec<String> {
118 let mut args = vec!["symbolic-ref".to_string()];
119 match &self.action {
120 SymbolicRefAction::Read { name, short } => {
121 if *short {
122 args.push("--short".into());
123 }
124 args.push(name.clone());
125 }
126 SymbolicRefAction::Set {
127 name,
128 target,
129 reason,
130 } => {
131 if let Some(r) = reason {
132 args.push("-m".into());
133 args.push(r.clone());
134 }
135 args.push(name.clone());
136 args.push(target.clone());
137 }
138 SymbolicRefAction::Delete { name, quiet } => {
139 args.push("--delete".into());
140 if *quiet {
141 args.push("-q".into());
142 }
143 args.push(name.clone());
144 }
145 }
146 args
147 }
148
149 async fn execute(&self) -> Result<String> {
150 if let SymbolicRefAction::Read { name, .. } | SymbolicRefAction::Set { name, .. } =
151 &self.action
152 {
153 if name.is_empty() {
154 return Err(Error::invalid_config("symbolic-ref requires a ref name"));
155 }
156 }
157 let out = self.execute_raw().await?;
158 Ok(out.stdout_trimmed())
159 }
160}