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
use crate::{util, AvailablePlugin, InstalledPlugin};
use anyhow::Result;
use std::fs;
use std::path::PathBuf;
const ICON_NAMES: [&str; 4] = ["icon@2x.png", "icon@2x.jpg", "icon.png", "icon.jpg"];
#[derive(Debug, Clone)]
pub struct Plugin {
pub(crate) installed: Option<InstalledPlugin>,
pub(crate) available: Option<AvailablePlugin>,
}
impl Plugin {
pub fn is_installed(&self) -> bool {
self.installed.is_some()
}
pub fn is_available(&self) -> bool {
self.available.is_some()
}
pub fn name(&self) -> &str {
if let Some(i) = &self.installed {
&i.name
} else if let Some(a) = &self.available {
&a.name
} else {
panic!("Plugin that is neither installed nor available")
}
}
pub fn path(&self) -> Option<PathBuf> {
Some(self.installed.as_ref()?.path())
}
pub fn retrieve_icon(&self) -> Option<Vec<u8>> {
if let Some(i) = &self.installed {
for name in ICON_NAMES.iter() {
let mut path = i.path();
path.push(name);
if path.exists() {
return std::fs::read(path).ok();
}
}
}
if let Some(a) = &self.available {
return util::download(a.icon_url.as_ref()?).ok();
}
None
}
pub fn download(&mut self) -> Result<()> {
self.installed = Some(
self.available
.as_ref()
.ok_or_else(|| anyhow!("Not an available Plug-In"))?
.download()?,
);
Ok(())
}
pub fn remove(&mut self) -> Result<()> {
if let Some(path) = self.path() {
info!("Removing {}", path.to_string_lossy());
fs::remove_dir_all(path)?;
self.installed = None;
Ok(())
} else {
Err(anyhow!("Not an installed Plug-In"))
}
}
pub fn versions(&self) -> (Option<&str>, Option<&str>) {
(
self.installed.as_ref().map(|i| i.version.as_str()),
self.available.as_ref().map(|a| a.version.as_str()),
)
}
}