mod codec;
pub mod config;
pub use self::codec::*;
use const_format::concatcp;
use serde::{Deserialize, Serialize};
use std::{
borrow::Cow,
path::{Path, PathBuf},
};
pub const LOCAL: &str = "~/.local/share/pop-launcher";
pub const LOCAL_PLUGINS: &str = concatcp!(LOCAL, "/plugins");
pub const SYSTEM: &str = "/etc/pop-launcher";
pub const SYSTEM_PLUGINS: &str = concatcp!(SYSTEM, "/plugins");
pub const DISTRIBUTION: &str = "/usr/lib/pop-launcher";
pub const DISTRIBUTION_PLUGINS: &str = concatcp!(DISTRIBUTION, "/plugins");
pub const PLUGIN_PATHS: &[&str] = &[LOCAL_PLUGINS, SYSTEM_PLUGINS, DISTRIBUTION_PLUGINS];
pub fn plugin_paths() -> impl Iterator<Item = Cow<'static, Path>> {
PLUGIN_PATHS.iter().map(|path| {
#[allow(deprecated)]
if let Some(path) = path.strip_prefix("~/") {
let path = dirs::home_dir()
.expect("user does not have home dir")
.join(path);
Cow::Owned(path)
} else {
Cow::Borrowed(Path::new(path))
}
})
}
pub type Generation = u32;
pub type Indice = u32;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ContextOption {
pub id: Indice,
pub name: String,
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
pub enum GpuPreference {
Default,
NonDefault,
SpecificIdx(u32),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum IconSource {
Name(Cow<'static, str>),
Mime(Cow<'static, str>),
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum PluginResponse {
Append(PluginSearchResult),
Clear,
Close,
Context {
id: Indice,
options: Vec<ContextOption>,
},
Deactivate,
DesktopEntry {
path: PathBuf,
gpu_preference: GpuPreference,
#[serde(skip_serializing_if = "Option::is_none", default)]
action_name: Option<String>,
},
Fill(String),
Finished,
}
#[derive(Debug, Default, Deserialize, Serialize, Clone)]
pub struct PluginSearchResult {
pub id: Indice,
pub name: String,
pub description: String,
pub keywords: Option<Vec<String>>,
pub icon: Option<IconSource>,
pub exec: Option<String>,
pub window: Option<(Generation, Indice)>,
}
impl PluginSearchResult {
#[must_use]
#[inline]
pub fn cache_identifier(&self) -> Option<String> {
self.exec.as_ref().map(|_| self.name.clone())
}
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum Request {
Activate(Indice),
ActivateContext { id: Indice, context: Indice },
Complete(Indice),
Context(Indice),
Exit,
Close,
Interrupt,
Quit(Indice),
Search(String),
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub enum Response {
Close,
Context {
id: Indice,
options: Vec<ContextOption>,
},
DesktopEntry {
path: PathBuf,
gpu_preference: GpuPreference,
action_name: Option<String>,
},
Update(Vec<SearchResult>),
Fill(String),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SearchResult {
pub id: Indice,
pub name: String,
pub description: String,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "::serde_with::rust::unwrap_or_skip"
)]
pub icon: Option<IconSource>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "::serde_with::rust::unwrap_or_skip"
)]
pub category_icon: Option<IconSource>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "::serde_with::rust::unwrap_or_skip"
)]
pub window: Option<(Generation, Indice)>,
}