Skip to main content

deepseek_rust_cli/tools/
git_tools.rs

1use std::{collections::HashMap, path::Path};
2
3use anyhow::Result;
4use async_trait::async_trait;
5use serde_json::Value;
6
7use crate::{agent::types::UndoAction, tools, tools::base::Tool};
8
9pub struct GitStatusTool;
10#[async_trait]
11impl Tool for GitStatusTool {
12    fn name(&self) -> &str {
13        "git_status"
14    }
15    async fn execute(
16        &self,
17        args: &HashMap<String, Value>,
18        _undo: &mut Vec<UndoAction>,
19        _cwd: Option<&Path>,
20    ) -> Result<String> {
21        let path = args.get("path").and_then(|v| v.as_str());
22        tools::git_ops::git_status(path).await
23    }
24}
25
26pub struct GitDiffTool;
27#[async_trait]
28impl Tool for GitDiffTool {
29    fn name(&self) -> &str {
30        "git_diff"
31    }
32    async fn execute(
33        &self,
34        args: &HashMap<String, Value>,
35        _undo: &mut Vec<UndoAction>,
36        _cwd: Option<&Path>,
37    ) -> Result<String> {
38        let path = args.get("path").and_then(|v| v.as_str());
39        let staged = args
40            .get("staged")
41            .and_then(|v| v.as_bool())
42            .unwrap_or(false);
43        tools::git_ops::git_diff(path, staged).await
44    }
45}
46
47pub struct GitLogTool;
48#[async_trait]
49impl Tool for GitLogTool {
50    fn name(&self) -> &str {
51        "git_log"
52    }
53    async fn execute(
54        &self,
55        args: &HashMap<String, Value>,
56        _undo: &mut Vec<UndoAction>,
57        _cwd: Option<&Path>,
58    ) -> Result<String> {
59        let path = args.get("path").and_then(|v| v.as_str());
60        let count = args
61            .get("count")
62            .and_then(|v| v.as_u64())
63            .map(|v| v as usize);
64        tools::git_ops::git_log(path, count).await
65    }
66}
67
68pub struct GitBranchTool;
69#[async_trait]
70impl Tool for GitBranchTool {
71    fn name(&self) -> &str {
72        "git_branch"
73    }
74    async fn execute(
75        &self,
76        args: &HashMap<String, Value>,
77        _undo: &mut Vec<UndoAction>,
78        _cwd: Option<&Path>,
79    ) -> Result<String> {
80        let path = args.get("path").and_then(|v| v.as_str());
81        let action = args.get("action").and_then(|v| v.as_str());
82        let name = args.get("name").and_then(|v| v.as_str());
83        tools::git_ops::git_branch(path, action, name).await
84    }
85}
86
87pub struct GitAddTool;
88#[async_trait]
89impl Tool for GitAddTool {
90    fn name(&self) -> &str {
91        "git_add"
92    }
93    async fn execute(
94        &self,
95        args: &HashMap<String, Value>,
96        _undo: &mut Vec<UndoAction>,
97        _cwd: Option<&Path>,
98    ) -> Result<String> {
99        let path = args.get("path").and_then(|v| v.as_str());
100        let files = args.get("files").and_then(|v| v.as_str());
101        tools::git_ops::git_add(path, files).await
102    }
103}
104
105pub struct GitCommitTool;
106#[async_trait]
107impl Tool for GitCommitTool {
108    fn name(&self) -> &str {
109        "git_commit"
110    }
111    async fn execute(
112        &self,
113        args: &HashMap<String, Value>,
114        _undo: &mut Vec<UndoAction>,
115        _cwd: Option<&Path>,
116    ) -> Result<String> {
117        let path = args.get("path").and_then(|v| v.as_str());
118        let message = args
119            .get("message")
120            .and_then(|v| v.as_str())
121            .ok_or_else(|| anyhow::anyhow!("Missing 'message'"))?;
122        tools::git_ops::git_commit(path, message).await
123    }
124}
125
126pub struct GitPushTool;
127#[async_trait]
128impl Tool for GitPushTool {
129    fn name(&self) -> &str {
130        "git_push"
131    }
132    async fn execute(
133        &self,
134        args: &HashMap<String, Value>,
135        _undo: &mut Vec<UndoAction>,
136        _cwd: Option<&Path>,
137    ) -> Result<String> {
138        let path = args.get("path").and_then(|v| v.as_str());
139        let remote = args.get("remote").and_then(|v| v.as_str());
140        let branch = args.get("branch").and_then(|v| v.as_str());
141        tools::git_ops::git_push(path, remote, branch).await
142    }
143}
144
145pub struct GitPullTool;
146#[async_trait]
147impl Tool for GitPullTool {
148    fn name(&self) -> &str {
149        "git_pull"
150    }
151    async fn execute(
152        &self,
153        args: &HashMap<String, Value>,
154        _undo: &mut Vec<UndoAction>,
155        _cwd: Option<&Path>,
156    ) -> Result<String> {
157        let path = args.get("path").and_then(|v| v.as_str());
158        let remote = args.get("remote").and_then(|v| v.as_str());
159        let branch = args.get("branch").and_then(|v| v.as_str());
160        tools::git_ops::git_pull(path, remote, branch).await
161    }
162}
163
164pub struct GitCheckoutTool;
165#[async_trait]
166impl Tool for GitCheckoutTool {
167    fn name(&self) -> &str {
168        "git_checkout"
169    }
170    async fn execute(
171        &self,
172        args: &HashMap<String, Value>,
173        _undo: &mut Vec<UndoAction>,
174        _cwd: Option<&Path>,
175    ) -> Result<String> {
176        let path = args.get("path").and_then(|v| v.as_str());
177        let target = args
178            .get("target")
179            .and_then(|v| v.as_str())
180            .ok_or_else(|| anyhow::anyhow!("Missing 'target'"))?;
181        tools::git_ops::git_checkout(path, target).await
182    }
183}
184
185pub struct GitCloneTool;
186#[async_trait]
187impl Tool for GitCloneTool {
188    fn name(&self) -> &str {
189        "git_clone"
190    }
191    async fn execute(
192        &self,
193        args: &HashMap<String, Value>,
194        _undo: &mut Vec<UndoAction>,
195        _cwd: Option<&Path>,
196    ) -> Result<String> {
197        let url = args
198            .get("url")
199            .and_then(|v| v.as_str())
200            .ok_or_else(|| anyhow::anyhow!("Missing 'url'"))?;
201        let dest = args.get("dest").and_then(|v| v.as_str());
202        tools::git_ops::git_clone(url, dest).await
203    }
204}
205
206pub struct GitRemoteListTool;
207#[async_trait]
208impl Tool for GitRemoteListTool {
209    fn name(&self) -> &str {
210        "git_remote_list"
211    }
212    async fn execute(
213        &self,
214        args: &HashMap<String, Value>,
215        _undo: &mut Vec<UndoAction>,
216        _cwd: Option<&Path>,
217    ) -> Result<String> {
218        let path = args.get("path").and_then(|v| v.as_str());
219        tools::git_ops::git_remote_list(path).await
220    }
221}
222
223pub struct GitStashTool;
224#[async_trait]
225impl Tool for GitStashTool {
226    fn name(&self) -> &str {
227        "git_stash"
228    }
229    async fn execute(
230        &self,
231        args: &HashMap<String, Value>,
232        _undo: &mut Vec<UndoAction>,
233        _cwd: Option<&Path>,
234    ) -> Result<String> {
235        let path = args.get("path").and_then(|v| v.as_str());
236        let action = args.get("action").and_then(|v| v.as_str());
237        tools::git_ops::git_stash(path, action).await
238    }
239}