1use crate::{
4 asyncjob::{AsyncJob, RunParams},
5 error::Result,
6 sync::cred::BasicAuthCredential,
7 sync::{
8 remotes::{get_default_remote, tags_missing_remote},
9 RepoPath,
10 },
11 AsyncGitNotification,
12};
13
14use std::sync::{Arc, Mutex};
15
16enum JobState {
17 Request(Option<BasicAuthCredential>),
18 Response(Result<Vec<String>>),
19}
20
21#[derive(Clone)]
23pub struct AsyncRemoteTagsJob {
24 state: Arc<Mutex<Option<JobState>>>,
25 repo: RepoPath,
26}
27
28impl AsyncRemoteTagsJob {
30 pub fn new(
32 repo: RepoPath,
33 basic_credential: Option<BasicAuthCredential>,
34 ) -> Self {
35 Self {
36 repo,
37 state: Arc::new(Mutex::new(Some(JobState::Request(
38 basic_credential,
39 )))),
40 }
41 }
42
43 pub fn result(&self) -> Option<Result<Vec<String>>> {
45 if let Ok(mut state) = self.state.lock() {
46 if let Some(state) = state.take() {
47 return match state {
48 JobState::Request(_) => None,
49 JobState::Response(result) => Some(result),
50 };
51 }
52 }
53
54 None
55 }
56}
57
58impl AsyncJob for AsyncRemoteTagsJob {
59 type Notification = AsyncGitNotification;
60 type Progress = ();
61
62 fn run(
63 &mut self,
64 _params: RunParams<Self::Notification, Self::Progress>,
65 ) -> Result<Self::Notification> {
66 if let Ok(mut state) = self.state.lock() {
67 *state = state.take().map(|state| match state {
68 JobState::Request(basic_credential) => {
69 let result = get_default_remote(&self.repo)
70 .and_then(|remote| {
71 tags_missing_remote(
72 &self.repo,
73 &remote,
74 basic_credential,
75 )
76 });
77
78 JobState::Response(result)
79 }
80 JobState::Response(result) => {
81 JobState::Response(result)
82 }
83 });
84 }
85
86 Ok(AsyncGitNotification::RemoteTags)
87 }
88}