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, RichWorktreeStatus, SortOrder,
14 StashDetail, StashEntry, StatusDigest, StatusOptions, SubmoduleInfo,
15 SubmoduleSummary, TagInfo, TreeEntry, WorktreeDetail, WorktreeInfo, WorktreeStatus,
16};
17
18fn join_err(e: tokio::task::JoinError) -> EndringerError {
20 EndringerError::TaskJoin { message: e.to_string() }
21}
22
23#[derive(Clone)]
29pub struct AsyncRepository {
30 inner: Arc<Repository>,
31}
32
33impl AsyncRepository {
34 pub async fn open(path: &Path) -> Result<Self> {
36 let path = path.to_path_buf();
37 let inner = tokio::task::spawn_blocking(move || repository(&path))
38 .await
39 .map_err(join_err)??;
40 Ok(AsyncRepository { inner: Arc::new(inner) })
41 }
42
43 pub async fn open_jj(path: &Path) -> Result<Self> {
45 let path = path.to_path_buf();
46 let inner = tokio::task::spawn_blocking(move || jj_repository(&path))
47 .await
48 .map_err(join_err)??;
49 Ok(AsyncRepository { inner: Arc::new(inner) })
50 }
51
52 pub async fn status_digest(&self) -> Result<StatusDigest> {
55 let r = Arc::clone(&self.inner);
56 tokio::task::spawn_blocking(move || r.status_digest()).await.map_err(join_err)?
57 }
58
59 pub async fn local_branches(&self) -> Result<Vec<BranchInfo>> {
62 let r = Arc::clone(&self.inner);
63 tokio::task::spawn_blocking(move || r.local_branches()).await.map_err(join_err)?
64 }
65
66 pub async fn remote_branches(&self) -> Result<Vec<BranchInfo>> {
67 let r = Arc::clone(&self.inner);
68 tokio::task::spawn_blocking(move || r.remote_branches()).await.map_err(join_err)?
69 }
70
71 pub async fn list_commits(&self) -> Result<Vec<CommitInfo>> {
74 let r = Arc::clone(&self.inner);
75 tokio::task::spawn_blocking(move || r.list_commits()).await.map_err(join_err)?
76 }
77
78 pub async fn list_commits_sorted(&self, order: SortOrder) -> Result<Vec<CommitInfo>> {
79 let r = Arc::clone(&self.inner);
80 tokio::task::spawn_blocking(move || r.list_commits_sorted(order)).await.map_err(join_err)?
81 }
82
83 pub async fn log_since(&self, since: SystemTime, until: SystemTime) -> Result<Vec<CommitInfo>> {
84 let r = Arc::clone(&self.inner);
85 tokio::task::spawn_blocking(move || r.log_since(since, until)).await.map_err(join_err)?
86 }
87
88 pub async fn find_commit(&self, id: CommitId) -> Result<CommitInfo> {
89 let r = Arc::clone(&self.inner);
90 tokio::task::spawn_blocking(move || r.find_commit(&id)).await.map_err(join_err)?
91 }
92
93 pub async fn query_commits(&self, query: CommitQuery) -> Result<CommitQueryResult> {
94 let r = Arc::clone(&self.inner);
95 tokio::task::spawn_blocking(move || r.query_commits(query)).await.map_err(join_err)?
96 }
97
98 pub async fn list_tags(&self) -> Result<Vec<TagInfo>> {
101 let r = Arc::clone(&self.inner);
102 tokio::task::spawn_blocking(move || r.list_tags()).await.map_err(join_err)?
103 }
104
105 pub async fn list_tags_sorted(&self, order: SortOrder) -> Result<Vec<TagInfo>> {
106 let r = Arc::clone(&self.inner);
107 tokio::task::spawn_blocking(move || r.list_tags_sorted(order)).await.map_err(join_err)?
108 }
109
110 pub async fn create_tag(&self, name: String) -> Result<()> {
111 let r = Arc::clone(&self.inner);
112 tokio::task::spawn_blocking(move || r.create_tag(&name)).await.map_err(join_err)?
113 }
114
115 pub async fn create_annotated_tag(&self, name: String, message: String) -> Result<()> {
116 let r = Arc::clone(&self.inner);
117 tokio::task::spawn_blocking(move || r.create_annotated_tag(&name, &message)).await.map_err(join_err)?
118 }
119
120 pub async fn delete_tag(&self, name: String) -> Result<()> {
121 let r = Arc::clone(&self.inner);
122 tokio::task::spawn_blocking(move || r.delete_tag(&name)).await.map_err(join_err)?
123 }
124
125 pub async fn diff(&self, from: CommitId, to: CommitId) -> Result<DiffSummary> {
128 let r = Arc::clone(&self.inner);
129 tokio::task::spawn_blocking(move || r.diff(&from, &to)).await.map_err(join_err)?
130 }
131
132 pub async fn remote_url(&self, name: String) -> Result<Option<String>> {
135 let r = Arc::clone(&self.inner);
136 tokio::task::spawn_blocking(move || r.remote_url(&name))
137 .await
138 .map_err(join_err)?
139 }
140
141 pub async fn is_dirty(&self) -> Result<bool> {
144 let r = Arc::clone(&self.inner);
145 tokio::task::spawn_blocking(move || r.is_dirty()).await.map_err(join_err)?
146 }
147
148 pub async fn merge_base(&self, a: CommitId, b: CommitId) -> Result<Option<CommitId>> {
151 let r = Arc::clone(&self.inner);
152 tokio::task::spawn_blocking(move || r.merge_base(&a, &b)).await.map_err(join_err)?
153 }
154
155 pub async fn is_ancestor(&self, candidate: CommitId, descendant: CommitId) -> Result<bool> {
156 let r = Arc::clone(&self.inner);
157 tokio::task::spawn_blocking(move || r.is_ancestor(&candidate, &descendant)).await.map_err(join_err)?
158 }
159
160 pub async fn blame(&self, path: std::path::PathBuf) -> Result<Vec<BlameEntry>> {
163 let r = Arc::clone(&self.inner);
164 tokio::task::spawn_blocking(move || r.blame(&path)).await.map_err(join_err)?
165 }
166
167 pub async fn worktree_status(&self) -> Result<WorktreeStatus> {
168 let r = Arc::clone(&self.inner);
169 tokio::task::spawn_blocking(move || r.worktree_status()).await.map_err(join_err)?
170 }
171
172 pub async fn rich_worktree_status(&self, options: StatusOptions) -> Result<RichWorktreeStatus> {
173 let r = Arc::clone(&self.inner);
174 tokio::task::spawn_blocking(move || r.rich_worktree_status(options)).await.map_err(join_err)?
175 }
176
177 pub async fn file_at_commit(
178 &self,
179 path: std::path::PathBuf,
180 commit_id: CommitId,
181 ) -> Result<Vec<u8>> {
182 let r = Arc::clone(&self.inner);
183 tokio::task::spawn_blocking(move || r.file_at_commit(&path, &commit_id)).await.map_err(join_err)?
184 }
185
186 pub async fn submodules(&self) -> Result<Vec<SubmoduleInfo>> {
187 let r = Arc::clone(&self.inner);
188 tokio::task::spawn_blocking(move || r.submodules()).await.map_err(join_err)?
189 }
190
191 pub async fn stash_entries(&self) -> Result<Vec<StashEntry>> {
192 let r = Arc::clone(&self.inner);
193 tokio::task::spawn_blocking(move || r.stash_entries()).await.map_err(join_err)?
194 }
195
196 pub async fn worktrees(&self) -> Result<Vec<WorktreeInfo>> {
197 let r = Arc::clone(&self.inner);
198 tokio::task::spawn_blocking(move || r.worktrees()).await.map_err(join_err)?
199 }
200
201 pub async fn ahead_behind(
204 &self,
205 local: CommitId,
206 upstream: CommitId,
207 ) -> Result<AheadBehind> {
208 let r = Arc::clone(&self.inner);
209 tokio::task::spawn_blocking(move || r.ahead_behind(&local, &upstream)).await.map_err(join_err)?
210 }
211
212 pub async fn branch_ahead_behind(
213 &self,
214 branch: String,
215 ) -> Result<Option<AheadBehind>> {
216 let r = Arc::clone(&self.inner);
217 tokio::task::spawn_blocking(move || r.branch_ahead_behind(&branch)).await.map_err(join_err)?
218 }
219
220 pub async fn repository_info(&self) -> Result<RepositoryInfo> {
223 let r = Arc::clone(&self.inner);
224 tokio::task::spawn_blocking(move || r.repository_info()).await.map_err(join_err)?
225 }
226
227 pub async fn branch_tracking(&self, branch: String) -> Result<BranchTrackingInfo> {
230 let r = Arc::clone(&self.inner);
231 tokio::task::spawn_blocking(move || r.branch_tracking(&branch)).await.map_err(join_err)?
232 }
233
234 pub async fn local_branch_tracking(&self) -> Result<Vec<BranchTrackingInfo>> {
235 let r = Arc::clone(&self.inner);
236 tokio::task::spawn_blocking(move || r.local_branch_tracking()).await.map_err(join_err)?
237 }
238
239 pub async fn is_merged_into(&self, branch: String, target: String) -> Result<bool> {
240 let r = Arc::clone(&self.inner);
241 tokio::task::spawn_blocking(move || r.is_merged_into(&branch, &target)).await.map_err(join_err)?
242 }
243
244 pub async fn operation_state(&self) -> Result<OperationState> {
247 let r = Arc::clone(&self.inner);
248 tokio::task::spawn_blocking(move || r.operation_state()).await.map_err(join_err)?
249 }
250
251 pub async fn unmerged_paths(&self) -> Result<Vec<std::path::PathBuf>> {
252 let r = Arc::clone(&self.inner);
253 tokio::task::spawn_blocking(move || r.unmerged_paths()).await.map_err(join_err)?
254 }
255
256 pub async fn conflict_summary(&self) -> Result<ConflictSummary> {
257 let r = Arc::clone(&self.inner);
258 tokio::task::spawn_blocking(move || r.conflict_summary()).await.map_err(join_err)?
259 }
260
261 pub async fn blame_at(&self, path: std::path::PathBuf, commit_id: CommitId) -> Result<Vec<BlameEntry>> {
264 let r = Arc::clone(&self.inner);
265 tokio::task::spawn_blocking(move || r.blame_at(&path, &commit_id)).await.map_err(join_err)?
266 }
267
268 pub async fn tree_at_commit(&self, commit_id: CommitId) -> Result<Vec<TreeEntry>> {
269 let r = Arc::clone(&self.inner);
270 tokio::task::spawn_blocking(move || r.tree_at_commit(&commit_id)).await.map_err(join_err)?
271 }
272
273 pub async fn tree_at_path(&self, commit_id: CommitId, path: std::path::PathBuf) -> Result<Vec<TreeEntry>> {
274 let r = Arc::clone(&self.inner);
275 tokio::task::spawn_blocking(move || r.tree_at_path(&commit_id, &path)).await.map_err(join_err)?
276 }
277
278 pub async fn remotes(&self) -> Result<Vec<RemoteInfo>> {
281 let r = Arc::clone(&self.inner);
282 tokio::task::spawn_blocking(move || r.remotes()).await.map_err(join_err)?
283 }
284
285 pub async fn references(&self) -> Result<Vec<RefInfo>> {
286 let r = Arc::clone(&self.inner);
287 tokio::task::spawn_blocking(move || r.references()).await.map_err(join_err)?
288 }
289
290 pub async fn references_by_kind(&self, kind: RefKind) -> Result<Vec<RefInfo>> {
291 let r = Arc::clone(&self.inner);
292 tokio::task::spawn_blocking(move || r.references_by_kind(kind)).await.map_err(join_err)?
293 }
294
295 pub async fn submodule_summaries(&self) -> Result<Vec<SubmoduleSummary>> {
298 let r = Arc::clone(&self.inner);
299 tokio::task::spawn_blocking(move || r.submodule_summaries()).await.map_err(join_err)?
300 }
301
302 pub async fn stash_detail(&self, index: usize) -> Result<StashDetail> {
303 let r = Arc::clone(&self.inner);
304 tokio::task::spawn_blocking(move || r.stash_detail(index)).await.map_err(join_err)?
305 }
306
307 pub async fn stash_diff(&self, index: usize) -> Result<DiffSummary> {
308 let r = Arc::clone(&self.inner);
309 tokio::task::spawn_blocking(move || r.stash_diff(index)).await.map_err(join_err)?
310 }
311
312 pub async fn worktree_details(&self) -> Result<Vec<WorktreeDetail>> {
313 let r = Arc::clone(&self.inner);
314 tokio::task::spawn_blocking(move || r.worktree_details()).await.map_err(join_err)?
315 }
316}