lib_poki_launcher/
lib.rs

1/***
2 * This file is part of Poki Launcher.
3 *
4 * Poki Launcher is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Poki Launcher is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Poki Launcher.  If not, see <https://www.gnu.org/licenses/>.
16 */
17/// Application configuration
18mod config;
19/// Interact with the app database
20mod db;
21/// Parse desktop entries
22mod desktop_entry;
23/// Run an app
24mod runner;
25/// Scan for desktop entries
26mod scan;
27pub mod hot_reload;
28
29use directories_next::ProjectDirs;
30use lazy_static::lazy_static;
31use serde::{Deserialize, Serialize};
32use std::fmt;
33use std::{
34    cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
35    path::PathBuf,
36};
37use uuid::Uuid;
38
39pub use crate::config::Config;
40pub use crate::db::AppsDB;
41
42/// Custom error types
43pub mod error {
44    pub use crate::db::AppDBError;
45    pub use crate::desktop_entry::EntryParseError;
46    pub use crate::runner::RunError;
47    pub use crate::scan::ScanError;
48}
49
50lazy_static! {
51    /// Object to get paths to various dir used by this app
52    ///
53    /// Namely:
54    /// - config_dir
55    /// - data_local_dir
56    static ref DIRS: ProjectDirs =
57        ProjectDirs::from("dev", "Ben Aaron Goldberg", "Poki-Launcher")
58            .unwrap();
59    /// Path to the DB file
60    pub static ref DB_PATH: PathBuf = {
61        let data_dir = DIRS.data_dir();
62        let mut db_path = data_dir.to_path_buf();
63        db_path.push("apps.db");
64        db_path
65    };
66    /// Path to the config file
67    pub static ref CFG_PATH: PathBuf = {
68        let config_dir = DIRS.config_dir();
69        config_dir.join("poki-launcher.hjson")
70    };
71}
72
73/// An app on your machine.
74#[derive(Debug, Default, Clone, Serialize, Deserialize)]
75pub struct App {
76    /// Display name of the app.
77    pub name: String,
78    /// The exec string used to run the app.
79    pub(crate) exec: Vec<String>,
80    /// Score of the app of the ranking algo.
81    score: f32,
82    /// Uuid used to uniquely identify this app.
83    /// This is saved to find the app later when the list changes.
84    pub uuid: String,
85    /// Icon name for this app.
86    /// The icon name has to be looked up in the system's icon
87    /// theme to get a file path.
88    pub icon: String,
89    /// If true, launch in terminal
90    pub(crate) terminal: bool,
91}
92
93impl App {
94    /// Create a new app.
95    pub fn new(
96        name: String,
97        icon: String,
98        exec: Vec<String>,
99        terminal: bool,
100    ) -> App {
101        App {
102            name,
103            icon,
104            exec,
105            uuid: Uuid::new_v4().to_string(),
106            score: 0.0,
107            terminal,
108        }
109    }
110
111    /// Set this app's name, icon, and exec to the values of the other app.
112    pub fn merge(&mut self, other: &App) {
113        self.name = other.name.clone();
114        self.icon = other.icon.clone();
115        self.exec = other.exec.clone();
116    }
117}
118
119impl PartialEq for App {
120    fn eq(&self, other: &Self) -> bool {
121        self.name == other.name
122            && self.exec == other.exec
123            && self.icon == other.icon
124    }
125}
126
127impl Eq for App {}
128
129impl Ord for App {
130    fn cmp(&self, other: &Self) -> Ordering {
131        self.name
132            .cmp(&other.name)
133            .then(self.exec.cmp(&other.exec))
134            .then(self.icon.cmp(&other.icon))
135    }
136}
137
138impl PartialOrd for App {
139    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
140        Some(self.cmp(other))
141    }
142}
143
144impl fmt::Display for App {
145    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146        write!(f, "{}", self.name)
147    }
148}