use tauri::plugin::TauriPlugin;
use tauri::Wry;
use crate::Shell;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Module {
JsHardening,
NavigationPolicy,
WindowState,
ShowOnReady,
RevealOnReopen,
Watchdog,
Presence,
Broker,
Stream,
Recovery,
Frameless,
Clipboard,
}
impl Module {
pub const ALL: [Module; 12] = [
Module::JsHardening,
Module::NavigationPolicy,
Module::WindowState,
Module::ShowOnReady,
Module::RevealOnReopen,
Module::Watchdog,
Module::Presence,
Module::Broker,
Module::Stream,
Module::Recovery,
Module::Frameless,
Module::Clipboard,
];
pub const STATE: [Module; 5] = [
Module::Broker,
Module::Stream,
Module::Recovery,
Module::Frameless,
Module::Clipboard,
];
pub const LIFECYCLE_OFF: [Module; 5] = [
Module::JsHardening,
Module::NavigationPolicy,
Module::Presence,
Module::Watchdog,
Module::WindowState,
];
pub const LIFECYCLE_HOST_OPT_IN: [Module; 1] = [Module::ShowOnReady];
pub fn name(self) -> &'static str {
match self {
Module::JsHardening => "js_hardening",
Module::NavigationPolicy => "navigation_policy",
Module::WindowState => "window_state",
Module::ShowOnReady => "show_on_ready",
Module::RevealOnReopen => "reveal_on_reopen",
Module::Watchdog => "watchdog",
Module::Presence => "presence",
Module::Broker => "broker",
Module::Stream => "stream",
Module::Recovery => "recovery",
Module::Frameless => "frameless",
Module::Clipboard => "clipboard",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct ModuleSet(u16);
impl ModuleSet {
pub fn all() -> Self {
Module::ALL.iter().fold(Self(0), |set, m| set.with(*m))
}
pub fn state_only() -> Self {
Module::STATE
.iter()
.fold(Self(0), |set, m| set.with(*m))
.with(Module::RevealOnReopen)
}
fn bit(module: Module) -> u16 {
1 << (module as u16)
}
pub fn contains(self, module: Module) -> bool {
self.0 & Self::bit(module) != 0
}
pub fn with(self, module: Module) -> Self {
Self(self.0 | Self::bit(module))
}
pub fn without(self, module: Module) -> Self {
Self(self.0 & !Self::bit(module))
}
pub fn lifecycle_only() -> Self {
Module::LIFECYCLE_OFF
.iter()
.chain(Module::LIFECYCLE_HOST_OPT_IN.iter())
.fold(Self::all(), |set, m| set.without(*m))
}
pub fn names(self) -> Vec<&'static str> {
Module::ALL
.iter()
.filter(|m| self.contains(**m))
.map(|m| m.name())
.collect()
}
}
pub struct ShellPlugin;
impl ShellPlugin {
pub fn builder() -> ShellPluginBuilder {
ShellPluginBuilder {
shell: None,
modules: ModuleSet::all(),
}
}
}
#[must_use]
pub struct ShellPluginBuilder {
shell: Option<Shell>,
modules: ModuleSet,
}
impl ShellPluginBuilder {
pub fn shell(mut self, shell: Shell) -> Self {
self.shell = Some(shell);
self
}
pub fn without(mut self, module: Module) -> Self {
self.modules = self.modules.without(module);
self
}
pub fn build(self) -> TauriPlugin<Wry> {
let shell = self.shell.expect(
"rightkit-tauri-shell: ShellPlugin::builder() needs .shell(Shell::builder(..).build())",
);
let mut cfg = shell.cfg;
cfg.modules = self.modules;
crate::install(cfg)
}
pub fn lifecycle_only(mut self) -> TauriPlugin<Wry> {
self.modules = ModuleSet::lifecycle_only();
if let Some(shell) = self.shell.as_mut() {
shell.cfg.lifecycle_only = true;
}
self.build()
}
pub fn install_state_only(mut self) -> TauriPlugin<Wry> {
self.modules = ModuleSet::state_only();
self.build()
}
}