1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//! ref: composer/src/Composer/Util/SyncHelper.php
use anyhow::Result;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use crate::downloader::download_manager::DownloadManager;
use crate::downloader::downloader_interface::DownloaderInterface;
use crate::package::package_interface::PackageInterface;
use crate::util::r#loop::Loop;
pub enum DownloaderOrManager<'a> {
Interface(&'a dyn DownloaderInterface),
Manager(&'a DownloadManager),
}
impl<'a> DownloaderOrManager<'a> {
fn download(&self, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.download(package, path, prev_package),
Self::Manager(d) => d.download(package, path, prev_package),
}
}
fn prepare(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.prepare(r#type, package, path, prev_package),
Self::Manager(d) => d.prepare(r#type, package, path, prev_package),
}
}
fn install(&self, package: &dyn PackageInterface, path: &str) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.install(package, path),
Self::Manager(d) => d.install(package, path),
}
}
fn update(&self, package: &dyn PackageInterface, prev_package: &dyn PackageInterface, path: &str) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.update(package, prev_package, path),
Self::Manager(d) => d.update(package, prev_package, path),
}
}
fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Box<dyn PromiseInterface> {
match self {
Self::Interface(d) => d.cleanup(r#type, package, path, prev_package),
Self::Manager(d) => d.cleanup(r#type, package, path, prev_package),
}
}
}
pub struct SyncHelper;
impl SyncHelper {
pub fn download_and_install_package_sync(
r#loop: &Loop,
downloader: DownloaderOrManager<'_>,
path: String,
package: &dyn PackageInterface,
prev_package: Option<&dyn PackageInterface>,
) -> Result<()> {
let r#type = if prev_package.is_some() { "update" } else { "install" };
let result: Result<()> = (|| {
Self::r#await(r#loop, Some(downloader.download(package, &path, prev_package)))?;
Self::r#await(r#loop, Some(downloader.prepare(r#type, package, &path, prev_package)))?;
if r#type == "update" {
if let Some(prev) = prev_package {
Self::r#await(r#loop, Some(downloader.update(package, prev, &path)))?;
}
} else {
Self::r#await(r#loop, Some(downloader.install(package, &path)))?;
}
Ok(())
})();
if result.is_err() {
Self::r#await(r#loop, Some(downloader.cleanup(r#type, package, &path, prev_package)))?;
return result;
}
Self::r#await(r#loop, Some(downloader.cleanup(r#type, package, &path, prev_package)))?;
Ok(())
}
pub fn r#await(r#loop: &Loop, promise: Option<Box<dyn PromiseInterface>>) -> Result<()> {
if let Some(promise) = promise {
r#loop.wait(vec![promise]);
}
Ok(())
}
}
|