gnostr_asyncgit/
treefiles.rs1use std::sync::{Arc, Mutex};
2
3use crate::{
4 asyncjob::{AsyncJob, RunParams},
5 error::Result,
6 sync::{tree_files, CommitId, RepoPath, TreeFile},
7 AsyncGitNotification,
8};
9
10pub struct FileTreeResult {
12 pub commit: CommitId,
14 pub result: Result<Vec<TreeFile>>,
16}
17
18enum JobState {
19 Request { commit: CommitId, repo: RepoPath },
20 Response(FileTreeResult),
21}
22
23#[derive(Clone, Default)]
25pub struct AsyncTreeFilesJob {
26 state: Arc<Mutex<Option<JobState>>>,
27}
28
29impl AsyncTreeFilesJob {
31 pub fn new(repo: RepoPath, commit: CommitId) -> Self {
33 Self {
34 state: Arc::new(Mutex::new(Some(JobState::Request { repo, commit }))),
35 }
36 }
37
38 pub fn result(&self) -> Option<FileTreeResult> {
40 if let Ok(mut state) = self.state.lock() {
41 if let Some(state) = state.take() {
42 return match state {
43 JobState::Request { .. } => None,
44 JobState::Response(result) => Some(result),
45 };
46 }
47 }
48
49 None
50 }
51}
52
53impl AsyncJob for AsyncTreeFilesJob {
54 type Notification = AsyncGitNotification;
55 type Progress = ();
56
57 fn run(
58 &mut self,
59 _params: RunParams<Self::Notification, Self::Progress>,
60 ) -> Result<Self::Notification> {
61 if let Ok(mut state) = self.state.lock() {
62 *state = state.take().map(|state| match state {
63 JobState::Request { commit, repo } => {
64 let files = tree_files(&repo, commit);
65
66 JobState::Response(FileTreeResult {
67 commit,
68 result: files,
69 })
70 }
71 JobState::Response(result) => JobState::Response(result),
72 });
73 }
74
75 Ok(AsyncGitNotification::TreeFiles)
76 }
77}