endringer_async/
async_api.rs1use std::path::Path;
4use std::sync::Arc;
5use std::time::SystemTime;
6
7use endringer::Error as EndringerError;
8use endringer::Result;
9use endringer::repository::{Repository, jj_repository, repository};
10use endringer::{
11 AheadBehind, BlameEntry, BranchInfo, BranchTrackingInfo, CommitId, CommitInfo,
12 CommitQuery, CommitQueryResult, ConflictSummary, DiffSummary, OperationState,
13 RefInfo, RefKind, RemoteInfo, RepositoryInfo, SortOrder, StashEntry,
14 StatusDigest, SubmoduleInfo, TagInfo, TreeEntry, WorktreeInfo, WorktreeStatus,
15};
16
17fn join_err(e: tokio::task::JoinError) -> EndringerError {
19 EndringerError::TaskJoin { message: e.to_string() }
20}
21
22#[derive(Clone)]
28pub struct AsyncRepository {
29 inner: Arc<Repository>,
30}
31
32impl AsyncRepository {
33 pub async fn open(path: &Path) -> Result<Self> {
35 let path = path.to_path_buf();
36 let inner = tokio::task::spawn_blocking(move || repository(&path))
37 .await
38 .map_err(join_err)??;
39 Ok(AsyncRepository { inner: Arc::new(inner) })
40 }
41
42 pub async fn open_jj(path: &Path) -> Result<Self> {
44 let path = path.to_path_buf();
45 let inner = tokio::task::spawn_blocking(move || jj_repository(&path))
46 .await
47 .map_err(join_err)??;
48 Ok(AsyncRepository { inner: Arc::new(inner) })
49 }
50
51 pub async fn status_digest(&self) -> Result<StatusDigest> {
54 let r = Arc::clone(&self.inner);
55 tokio::task::spawn_blocking(move || r.status_digest()).await.map_err(join_err)?
56 }
57
58 pub async fn local_branches(&self) -> Result<Vec<BranchInfo>> {
61 let r = Arc::clone(&self.inner);
62 tokio::task::spawn_blocking(move || r.local_branches()).await.map_err(join_err)?
63 }
64
65 pub async fn remote_branches(&self) -> Result<Vec<BranchInfo>> {
66 let r = Arc::clone(&self.inner);
67 tokio::task::spawn_blocking(move || r.remote_branches()).await.map_err(join_err)?
68 }
69
70 pub async fn list_commits(&self) -> Result<Vec<CommitInfo>> {
73 let r = Arc::clone(&self.inner);
74 tokio::task::spawn_blocking(move || r.list_commits()).await.map_err(join_err)?
75 }
76
77 pub async fn list_commits_sorted(&self, order: SortOrder) -> Result<Vec<CommitInfo>> {
78 let r = Arc::clone(&self.inner);
79 tokio::task::spawn_blocking(move || r.list_commits_sorted(order)).await.map_err(join_err)?
80 }
81
82 pub async fn log_since(&self, since: SystemTime, until: SystemTime) -> Result<Vec<CommitInfo>> {
83 let r = Arc::clone(&self.inner);
84 tokio::task::spawn_blocking(move || r.log_since(since, until)).await.map_err(join_err)?
85 }
86
87 pub async fn find_commit(&self, id: CommitId) -> Result<CommitInfo> {
88 let r = Arc::clone(&self.inner);
89 tokio::task::spawn_blocking(move || r.find_commit(&id)).await.map_err(join_err)?
90 }
91
92 pub async fn query_commits(&self, query: CommitQuery) -> Result<CommitQueryResult> {
93 let r = Arc::clone(&self.inner);
94 tokio::task::spawn_blocking(move || r.query_commits(query)).await.map_err(join_err)?
95 }
96
97 pub async fn list_tags(&self) -> Result<Vec<TagInfo>> {
100 let r = Arc::clone(&self.inner);
101 tokio::task::spawn_blocking(move || r.list_tags()).await.map_err(join_err)?
102 }
103
104 pub async fn list_tags_sorted(&self, order: SortOrder) -> Result<Vec<TagInfo>> {
105 let r = Arc::clone(&self.inner);
106 tokio::task::spawn_blocking(move || r.list_tags_sorted(order)).await.map_err(join_err)?
107 }
108
109 pub async fn create_tag(&self, name: String) -> Result<()> {
110 let r = Arc::clone(&self.inner);
111 tokio::task::spawn_blocking(move || r.create_tag(&name)).await.map_err(join_err)?
112 }
113
114 pub async fn create_annotated_tag(&self, name: String, message: String) -> Result<()> {
115 let r = Arc::clone(&self.inner);
116 tokio::task::spawn_blocking(move || r.create_annotated_tag(&name, &message)).await.map_err(join_err)?
117 }
118
119 pub async fn delete_tag(&self, name: String) -> Result<()> {
120 let r = Arc::clone(&self.inner);
121 tokio::task::spawn_blocking(move || r.delete_tag(&name)).await.map_err(join_err)?
122 }
123
124 pub async fn diff(&self, from: CommitId, to: CommitId) -> Result<DiffSummary> {
127 let r = Arc::clone(&self.inner);
128 tokio::task::spawn_blocking(move || r.diff(&from, &to)).await.map_err(join_err)?
129 }
130
131 pub async fn remote_url(&self, name: String) -> Result<Option<String>> {
134 let r = Arc::clone(&self.inner);
135 tokio::task::spawn_blocking(move || r.remote_url(&name))
136 .await
137 .map_err(join_err)?
138 }
139
140 pub async fn is_dirty(&self) -> Result<bool> {
143 let r = Arc::clone(&self.inner);
144 tokio::task::spawn_blocking(move || r.is_dirty()).await.map_err(join_err)?
145 }
146
147 pub async fn merge_base(&self, a: CommitId, b: CommitId) -> Result<Option<CommitId>> {
150 let r = Arc::clone(&self.inner);
151 tokio::task::spawn_blocking(move || r.merge_base(&a, &b)).await.map_err(join_err)?
152 }
153
154 pub async fn is_ancestor(&self, candidate: CommitId, descendant: CommitId) -> Result<bool> {
155 let r = Arc::clone(&self.inner);
156 tokio::task::spawn_blocking(move || r.is_ancestor(&candidate, &descendant)).await.map_err(join_err)?
157 }
158
159 pub async fn blame(&self, path: std::path::PathBuf) -> Result<Vec<BlameEntry>> {
162 let r = Arc::clone(&self.inner);
163 tokio::task::spawn_blocking(move || r.blame(&path)).await.map_err(join_err)?
164 }
165
166 pub async fn worktree_status(&self) -> Result<WorktreeStatus> {
167 let r = Arc::clone(&self.inner);
168 tokio::task::spawn_blocking(move || r.worktree_status()).await.map_err(join_err)?
169 }
170
171 pub async fn file_at_commit(
172 &self,
173 path: std::path::PathBuf,
174 commit_id: CommitId,
175 ) -> Result<Vec<u8>> {
176 let r = Arc::clone(&self.inner);
177 tokio::task::spawn_blocking(move || r.file_at_commit(&path, &commit_id)).await.map_err(join_err)?
178 }
179
180 pub async fn submodules(&self) -> Result<Vec<SubmoduleInfo>> {
181 let r = Arc::clone(&self.inner);
182 tokio::task::spawn_blocking(move || r.submodules()).await.map_err(join_err)?
183 }
184
185 pub async fn stash_entries(&self) -> Result<Vec<StashEntry>> {
186 let r = Arc::clone(&self.inner);
187 tokio::task::spawn_blocking(move || r.stash_entries()).await.map_err(join_err)?
188 }
189
190 pub async fn worktrees(&self) -> Result<Vec<WorktreeInfo>> {
191 let r = Arc::clone(&self.inner);
192 tokio::task::spawn_blocking(move || r.worktrees()).await.map_err(join_err)?
193 }
194
195 pub async fn ahead_behind(
198 &self,
199 local: CommitId,
200 upstream: CommitId,
201 ) -> Result<AheadBehind> {
202 let r = Arc::clone(&self.inner);
203 tokio::task::spawn_blocking(move || r.ahead_behind(&local, &upstream)).await.map_err(join_err)?
204 }
205
206 pub async fn branch_ahead_behind(
207 &self,
208 branch: String,
209 ) -> Result<Option<AheadBehind>> {
210 let r = Arc::clone(&self.inner);
211 tokio::task::spawn_blocking(move || r.branch_ahead_behind(&branch)).await.map_err(join_err)?
212 }
213
214 pub async fn repository_info(&self) -> Result<RepositoryInfo> {
217 let r = Arc::clone(&self.inner);
218 tokio::task::spawn_blocking(move || r.repository_info()).await.map_err(join_err)?
219 }
220
221 pub async fn branch_tracking(&self, branch: String) -> Result<BranchTrackingInfo> {
224 let r = Arc::clone(&self.inner);
225 tokio::task::spawn_blocking(move || r.branch_tracking(&branch)).await.map_err(join_err)?
226 }
227
228 pub async fn local_branch_tracking(&self) -> Result<Vec<BranchTrackingInfo>> {
229 let r = Arc::clone(&self.inner);
230 tokio::task::spawn_blocking(move || r.local_branch_tracking()).await.map_err(join_err)?
231 }
232
233 pub async fn is_merged_into(&self, branch: String, target: String) -> Result<bool> {
234 let r = Arc::clone(&self.inner);
235 tokio::task::spawn_blocking(move || r.is_merged_into(&branch, &target)).await.map_err(join_err)?
236 }
237
238 pub async fn operation_state(&self) -> Result<OperationState> {
241 let r = Arc::clone(&self.inner);
242 tokio::task::spawn_blocking(move || r.operation_state()).await.map_err(join_err)?
243 }
244
245 pub async fn unmerged_paths(&self) -> Result<Vec<std::path::PathBuf>> {
246 let r = Arc::clone(&self.inner);
247 tokio::task::spawn_blocking(move || r.unmerged_paths()).await.map_err(join_err)?
248 }
249
250 pub async fn conflict_summary(&self) -> Result<ConflictSummary> {
251 let r = Arc::clone(&self.inner);
252 tokio::task::spawn_blocking(move || r.conflict_summary()).await.map_err(join_err)?
253 }
254
255 pub async fn blame_at(&self, path: std::path::PathBuf, commit_id: CommitId) -> Result<Vec<BlameEntry>> {
258 let r = Arc::clone(&self.inner);
259 tokio::task::spawn_blocking(move || r.blame_at(&path, &commit_id)).await.map_err(join_err)?
260 }
261
262 pub async fn tree_at_commit(&self, commit_id: CommitId) -> Result<Vec<TreeEntry>> {
263 let r = Arc::clone(&self.inner);
264 tokio::task::spawn_blocking(move || r.tree_at_commit(&commit_id)).await.map_err(join_err)?
265 }
266
267 pub async fn tree_at_path(&self, commit_id: CommitId, path: std::path::PathBuf) -> Result<Vec<TreeEntry>> {
268 let r = Arc::clone(&self.inner);
269 tokio::task::spawn_blocking(move || r.tree_at_path(&commit_id, &path)).await.map_err(join_err)?
270 }
271
272 pub async fn remotes(&self) -> Result<Vec<RemoteInfo>> {
275 let r = Arc::clone(&self.inner);
276 tokio::task::spawn_blocking(move || r.remotes()).await.map_err(join_err)?
277 }
278
279 pub async fn references(&self) -> Result<Vec<RefInfo>> {
280 let r = Arc::clone(&self.inner);
281 tokio::task::spawn_blocking(move || r.references()).await.map_err(join_err)?
282 }
283
284 pub async fn references_by_kind(&self, kind: RefKind) -> Result<Vec<RefInfo>> {
285 let r = Arc::clone(&self.inner);
286 tokio::task::spawn_blocking(move || r.references_by_kind(kind)).await.map_err(join_err)?
287 }
288}