Skip to main content

ahiru_tpm/
plugin.rs

1use std::{fmt::Display, path::PathBuf};
2
3use once_cell::sync::OnceCell;
4use url::Url;
5
6use crate::{attribute::Attribute, plugins, repo_url::RepoUrl, spec::Spec, tmux, utils};
7
8pub struct Plugin {
9    spec: Spec,
10    // TODO: Once `std::cell::OnceCell::get_or_try_init` is stable replace `once_cell` crate with
11    //       `std::cell`
12    path: OnceCell<PathBuf>,
13}
14
15impl Plugin {
16    pub fn url(&self) -> Url {
17        self.spec.url().into()
18    }
19
20    pub fn repo_url(&self) -> &RepoUrl {
21        self.spec.url()
22    }
23
24    pub fn name(&self) -> &str {
25        self.spec
26            .attributes()
27            .get(&Attribute::Alias)
28            .unwrap_or_else(|| self.spec.name())
29    }
30
31    pub fn is_installed(&self) -> bool {
32        self.path().exists()
33    }
34
35    pub fn path(&self) -> &PathBuf {
36        self.path
37            .get_or_init(|| tmux::get_plugins_dir().join(self.name()))
38    }
39
40    pub fn branch(&self) -> Option<&str> {
41        self.spec.branch()
42    }
43
44    pub fn parallel(&self) -> bool {
45        self.spec
46            .attributes()
47            .get(&Attribute::Parallel)
48            .and_then(|s| utils::parse_bool(s))
49            .unwrap_or_else(plugins::do_parallel)
50    }
51}
52
53impl From<Spec> for Plugin {
54    fn from(spec: Spec) -> Self {
55        Plugin {
56            spec,
57            path: OnceCell::new(),
58        }
59    }
60}
61
62impl Display for Plugin {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        write!(f, "{} ({}", self.name(), self.repo_url())?;
65        if let Some(branch) = self.branch() {
66            write!(f, "#{branch}")?;
67        };
68        write!(f, ")")
69    }
70}