fix(core): fix warnings
This commit is contained in:
parent
2aa5c03246
commit
8f11bf6cc6
|
@ -95,7 +95,7 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
|
||||||
.expect("unable to initialize config watcher thread");
|
.expect("unable to initialize config watcher thread");
|
||||||
|
|
||||||
let (_keyboard_layout_watcher_notify, keyboard_layout_watcher_signal) = unbounded::<()>();
|
let (_keyboard_layout_watcher_notify, keyboard_layout_watcher_signal) = unbounded::<()>();
|
||||||
keyboard_layout_watcher::initialize_and_spawn(_keyboard_layout_watcher_notify.clone())
|
keyboard_layout_watcher::initialize_and_spawn(_keyboard_layout_watcher_notify)
|
||||||
.expect("unable to initialize keyboard layout watcher thread");
|
.expect("unable to initialize keyboard layout watcher thread");
|
||||||
|
|
||||||
let config_store =
|
let config_store =
|
||||||
|
@ -198,7 +198,7 @@ fn daemon_main(args: CliModuleArgs) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn terminate_worker_if_already_running(runtime_dir: &Path) {
|
fn terminate_worker_if_already_running(runtime_dir: &Path) {
|
||||||
let lock_file = acquire_worker_lock(&runtime_dir);
|
let lock_file = acquire_worker_lock(runtime_dir);
|
||||||
if lock_file.is_some() {
|
if lock_file.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ fn spawn_worker(
|
||||||
];
|
];
|
||||||
if let Some(start_reason) = &start_reason {
|
if let Some(start_reason) = &start_reason {
|
||||||
args.push("--start-reason");
|
args.push("--start-reason");
|
||||||
args.push(&start_reason);
|
args.push(start_reason);
|
||||||
}
|
}
|
||||||
command.args(&args);
|
command.args(&args);
|
||||||
command.with_paths_overrides(paths_overrides);
|
command.with_paths_overrides(paths_overrides);
|
||||||
|
@ -313,7 +313,7 @@ fn restart_worker(
|
||||||
|
|
||||||
if !has_timed_out {
|
if !has_timed_out {
|
||||||
spawn_worker(
|
spawn_worker(
|
||||||
&paths_overrides,
|
paths_overrides,
|
||||||
exit_notify,
|
exit_notify,
|
||||||
start_reason,
|
start_reason,
|
||||||
);
|
);
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub fn load_config_or_troubleshoot(paths: &Paths, paths_overrides: &PathsOverrid
|
||||||
match crate::load_config(&paths.config, &paths.packages) {
|
match crate::load_config(&paths.config, &paths.packages) {
|
||||||
Ok(load_result) => {
|
Ok(load_result) => {
|
||||||
if load_result.non_fatal_errors.is_empty() {
|
if load_result.non_fatal_errors.is_empty() {
|
||||||
return LoadResult::Correct(load_result);
|
LoadResult::Correct(load_result)
|
||||||
} else {
|
} else {
|
||||||
let mut troubleshoot_handle = None;
|
let mut troubleshoot_handle = None;
|
||||||
|
|
||||||
|
@ -96,13 +96,13 @@ pub fn load_config_or_troubleshoot(paths: &Paths, paths_overrides: &PathsOverrid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoadResult::Warning(load_result, troubleshoot_handle);
|
LoadResult::Warning(load_result, troubleshoot_handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return LoadResult::Fatal(
|
LoadResult::Fatal(
|
||||||
launch_troubleshoot(paths_overrides).expect("unable to launch troubleshoot GUI"),
|
launch_troubleshoot(paths_overrides).expect("unable to launch troubleshoot GUI"),
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,11 +78,9 @@ fn watcher_main(config_dir: &Path, watcher_notify: &Sender<()>) {
|
||||||
if ["yml", "yaml"].iter().any(|ext| ext == &extension) {
|
if ["yml", "yaml"].iter().any(|ext| ext == &extension) {
|
||||||
// Only load non-hidden yml files
|
// Only load non-hidden yml files
|
||||||
!is_file_hidden(&path)
|
!is_file_hidden(&path)
|
||||||
} else if extension == "" {
|
|
||||||
// No extension, probably a folder
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
// If there is no extension, it's probably a folder
|
||||||
|
extension.is_empty()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -112,9 +110,9 @@ fn is_file_hidden(path: &Path) -> bool {
|
||||||
.file_name()
|
.file_name()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.starts_with(".");
|
.starts_with('.');
|
||||||
|
|
||||||
return starts_with_dot || has_hidden_attribute(path);
|
starts_with_dot || has_hidden_attribute(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -126,11 +124,7 @@ fn has_hidden_attribute(path: &Path) -> bool {
|
||||||
}
|
}
|
||||||
let attributes = metadata.unwrap().file_attributes();
|
let attributes = metadata.unwrap().file_attributes();
|
||||||
|
|
||||||
if (attributes & 0x2) > 0 {
|
(attributes & 0x2) > 0
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn new() -> CliModule {
|
||||||
|
|
||||||
#[cfg(feature = "modulo")]
|
#[cfg(feature = "modulo")]
|
||||||
fn launcher_main(args: CliModuleArgs) -> i32 {
|
fn launcher_main(args: CliModuleArgs) -> i32 {
|
||||||
use espanso_modulo::wizard::{DetectedOS, MigrationResult, WizardHandlers, WizardOptions};
|
use espanso_modulo::wizard::{MigrationResult, WizardHandlers, WizardOptions};
|
||||||
let paths = args.paths.expect("missing paths in launcher main");
|
let paths = args.paths.expect("missing paths in launcher main");
|
||||||
|
|
||||||
// TODO: should we create a non-gui wizard? We can also use it for the non-modulo versions of espanso
|
// TODO: should we create a non-gui wizard? We can also use it for the non-modulo versions of espanso
|
||||||
|
@ -84,8 +84,8 @@ fn launcher_main(args: CliModuleArgs) -> i32 {
|
||||||
Box::new(move || match util::migrate_configuration(&paths_clone) {
|
Box::new(move || match util::migrate_configuration(&paths_clone) {
|
||||||
Ok(_) => MigrationResult::Success,
|
Ok(_) => MigrationResult::Success,
|
||||||
Err(error) => match error.downcast_ref::<MigrationError>() {
|
Err(error) => match error.downcast_ref::<MigrationError>() {
|
||||||
Some(MigrationError::DirtyError) => MigrationResult::DirtyFailure,
|
Some(MigrationError::Dirty) => MigrationResult::DirtyFailure,
|
||||||
Some(MigrationError::CleanError) => MigrationResult::CleanFailure,
|
Some(MigrationError::Clean) => MigrationResult::CleanFailure,
|
||||||
_ => MigrationResult::UnknownFailure,
|
_ => MigrationResult::UnknownFailure,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -94,13 +94,11 @@ fn launcher_main(args: CliModuleArgs) -> i32 {
|
||||||
if cfg!(not(target_os = "linux")) && !preferences.has_completed_wizard() {
|
if cfg!(not(target_os = "linux")) && !preferences.has_completed_wizard() {
|
||||||
if cfg!(target_os = "macos") {
|
if cfg!(target_os = "macos") {
|
||||||
!crate::path::is_espanso_in_path()
|
!crate::path::is_espanso_in_path()
|
||||||
} else {
|
} else if paths.is_portable_mode {
|
||||||
if paths.is_portable_mode {
|
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
!crate::path::is_espanso_in_path()
|
!crate::path::is_espanso_in_path()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
@ -118,14 +116,13 @@ fn launcher_main(args: CliModuleArgs) -> i32 {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
let is_accessibility_enabled_handler =
|
let is_accessibility_enabled_handler =
|
||||||
Box::new(move || accessibility::is_accessibility_enabled());
|
Box::new(accessibility::is_accessibility_enabled);
|
||||||
let enable_accessibility_handler = Box::new(move || {
|
let enable_accessibility_handler = Box::new(move || {
|
||||||
accessibility::prompt_enable_accessibility();
|
accessibility::prompt_enable_accessibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
let preferences_clone = preferences.clone();
|
|
||||||
let on_completed_handler = Box::new(move || {
|
let on_completed_handler = Box::new(move || {
|
||||||
preferences_clone.set_completed_wizard(true);
|
preferences.set_completed_wizard(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only show the wizard if a panel should be displayed
|
// Only show the wizard if a panel should be displayed
|
||||||
|
|
|
@ -27,11 +27,7 @@ use crate::{exit_code::{MIGRATE_CLEAN_FAILURE, MIGRATE_DIRTY_FAILURE}, lock::acq
|
||||||
|
|
||||||
pub fn is_legacy_version_running(runtime_path: &Path) -> bool {
|
pub fn is_legacy_version_running(runtime_path: &Path) -> bool {
|
||||||
let legacy_lock_file = acquire_legacy_lock(runtime_path);
|
let legacy_lock_file = acquire_legacy_lock(runtime_path);
|
||||||
if legacy_lock_file.is_none() {
|
legacy_lock_file.is_none()
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn migrate_configuration(paths: &Paths) -> Result<()> {
|
pub fn migrate_configuration(paths: &Paths) -> Result<()> {
|
||||||
|
@ -58,9 +54,9 @@ pub fn migrate_configuration(paths: &Paths) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
match result.code() {
|
match result.code() {
|
||||||
Some(code) if code == MIGRATE_CLEAN_FAILURE => Err(MigrationError::CleanError.into()),
|
Some(code) if code == MIGRATE_CLEAN_FAILURE => Err(MigrationError::Clean.into()),
|
||||||
Some(code) if code == MIGRATE_DIRTY_FAILURE=> Err(MigrationError::DirtyError.into()),
|
Some(code) if code == MIGRATE_DIRTY_FAILURE=> Err(MigrationError::Dirty.into()),
|
||||||
_ => Err(MigrationError::UnexpectedError.into())
|
_ => Err(MigrationError::Unexpected.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,13 +64,13 @@ pub fn migrate_configuration(paths: &Paths) -> Result<()> {
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum MigrationError {
|
pub enum MigrationError {
|
||||||
#[error("clean error")]
|
#[error("clean error")]
|
||||||
CleanError,
|
Clean,
|
||||||
|
|
||||||
#[error("dirty error")]
|
#[error("dirty error")]
|
||||||
DirtyError,
|
Dirty,
|
||||||
|
|
||||||
#[error("unexpected error")]
|
#[error("unexpected error")]
|
||||||
UnexpectedError,
|
Unexpected,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_espanso_to_path() -> Result<()> {
|
pub fn add_espanso_to_path() -> Result<()> {
|
||||||
|
|
|
@ -43,11 +43,9 @@ fn log_main(args: CliModuleArgs) -> i32 {
|
||||||
let log_file = File::open(log_file);
|
let log_file = File::open(log_file);
|
||||||
if let Ok(log_file) = log_file {
|
if let Ok(log_file) = log_file {
|
||||||
let reader = BufReader::new(log_file);
|
let reader = BufReader::new(log_file);
|
||||||
for line in reader.lines() {
|
for line in reader.lines().flatten() {
|
||||||
if let Ok(line) = line {
|
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Error reading log file");
|
eprintln!("Error reading log file");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
|
|
||||||
println!("\n{}\n", "Welcome to espanso v2!".bold());
|
println!("\n{}\n", "Welcome to espanso v2!".bold());
|
||||||
println!("This migration tool will help you to smoothly transition to the new espanso v2 configuration format.");
|
println!("This migration tool will help you to smoothly transition to the new espanso v2 configuration format.");
|
||||||
println!("");
|
println!();
|
||||||
println!(
|
println!(
|
||||||
"1. Firstly, espanso will {} your current configuration, located in:\n",
|
"1. Firstly, espanso will {} your current configuration, located in:\n",
|
||||||
"backup".green().bold()
|
"backup".green().bold()
|
||||||
|
@ -80,7 +80,7 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
"convert".bold().green()
|
"convert".bold().green()
|
||||||
);
|
);
|
||||||
println!(" the current content of the config directory.");
|
println!(" the current content of the config directory.");
|
||||||
println!("");
|
println!();
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"backing up the configuration directory: '{}'",
|
"backing up the configuration directory: '{}'",
|
||||||
|
@ -91,16 +91,13 @@ fn migrate_main(args: CliModuleArgs) -> i32 {
|
||||||
target_backup_dir.to_string_lossy()
|
target_backup_dir.to_string_lossy()
|
||||||
);
|
);
|
||||||
|
|
||||||
if !cli_args.is_present("noconfirm") {
|
if !cli_args.is_present("noconfirm") && !Confirm::new()
|
||||||
if !Confirm::new()
|
|
||||||
.with_prompt("Do you want to proceed?")
|
.with_prompt("Do you want to proceed?")
|
||||||
.default(true)
|
.default(true)
|
||||||
.interact()
|
.interact()
|
||||||
.expect("unable to read choice")
|
.expect("unable to read choice") {
|
||||||
{
|
|
||||||
return MIGRATE_USER_ABORTED;
|
return MIGRATE_USER_ABORTED;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
println!("Backing up your configuration...");
|
println!("Backing up your configuration...");
|
||||||
update_panic_exit_code(MIGRATE_CLEAN_FAILURE);
|
update_panic_exit_code(MIGRATE_CLEAN_FAILURE);
|
||||||
|
|
|
@ -57,7 +57,7 @@ fn modulo_main(args: CliModuleArgs) -> i32 {
|
||||||
return welcome::welcome_main(matches, &paths, &icon_paths);
|
return welcome::welcome_main(matches, &paths, &icon_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(_) = cli_args.subcommand_matches("troubleshoot") {
|
if cli_args.subcommand_matches("troubleshoot").is_some() {
|
||||||
return troubleshoot::troubleshoot_main(&paths, &icon_paths);
|
return troubleshoot::troubleshoot_main(&paths, &icon_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ use crate::icon::IconPaths;
|
||||||
use espanso_modulo::welcome::*;
|
use espanso_modulo::welcome::*;
|
||||||
use espanso_path::Paths;
|
use espanso_path::Paths;
|
||||||
|
|
||||||
pub fn welcome_main(matches: &ArgMatches, paths: &Paths, icon_paths: &IconPaths) -> i32 {
|
pub fn welcome_main(matches: &ArgMatches, _: &Paths, icon_paths: &IconPaths) -> i32 {
|
||||||
let dont_show_again_handler = Box::new(move |dont_show: bool| {
|
let dont_show_again_handler = Box::new(move |_dont_show: bool| {
|
||||||
//preferences.set_should_display_welcome(!dont_show);
|
//preferences.set_should_display_welcome(!dont_show);
|
||||||
// TODO: this should probably be deleted if not used?
|
// TODO: this should probably be deleted if not used?
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn update_package(paths: &Paths, matches: &ArgMatches) -> Result<UpdateResul
|
||||||
let mut update_errors = Vec::new();
|
let mut update_errors = Vec::new();
|
||||||
|
|
||||||
for package_name in &packages_to_update {
|
for package_name in &packages_to_update {
|
||||||
if let Err(err) = perform_package_update(paths, &*archiver, &package_name) {
|
if let Err(err) = perform_package_update(paths, &*archiver, package_name) {
|
||||||
error_eprintln!("error updating package '{}': {:?}", package_name, err);
|
error_eprintln!("error updating package '{}': {:?}", package_name, err);
|
||||||
update_errors.push(err);
|
update_errors.push(err);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{CliModule, CliModuleArgs};
|
use super::{CliModule, CliModuleArgs};
|
||||||
use crate::{error_eprintln, exit_code::{WORKAROUND_FAILURE, WORKAROUND_SUCCESS}};
|
use crate::{error_eprintln, exit_code::{WORKAROUND_SUCCESS}};
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
mod secure_input;
|
mod secure_input;
|
||||||
|
@ -37,6 +37,7 @@ fn workaround_main(args: CliModuleArgs) -> i32 {
|
||||||
if cli_args.subcommand_matches("secure-input").is_some() {
|
if cli_args.subcommand_matches("secure-input").is_some() {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
|
use crate::exit_code::WORKAROUND_FAILURE;
|
||||||
if let Err(err) = secure_input::run_secure_input_workaround() {
|
if let Err(err) = secure_input::run_secure_input_workaround() {
|
||||||
error_eprintln!("secure-input workaround reported error: {}", err);
|
error_eprintln!("secure-input workaround reported error: {}", err);
|
||||||
return WORKAROUND_FAILURE;
|
return WORKAROUND_FAILURE;
|
||||||
|
|
|
@ -33,6 +33,5 @@ pub fn create_match_trigger_search_bar(
|
||||||
triggers: trigger.map(|trigger| vec![trigger]).unwrap_or_default(),
|
triggers: trigger.map(|trigger| vec![trigger]).unwrap_or_default(),
|
||||||
hotkey,
|
hotkey,
|
||||||
action: |_| EventType::ShowSearchBar,
|
action: |_| EventType::ShowSearchBar,
|
||||||
..Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ impl<'a> ConfigManager<'a> {
|
||||||
pub fn active_context(&self) -> (Arc<dyn Config>, MatchSet) {
|
pub fn active_context(&self) -> (Arc<dyn Config>, MatchSet) {
|
||||||
let config = self.active();
|
let config = self.active();
|
||||||
let match_paths = config.match_paths();
|
let match_paths = config.match_paths();
|
||||||
(config.clone(), self.match_store.query(&match_paths))
|
(config.clone(), self.match_store.query(match_paths))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default(&self) -> Arc<dyn Config> {
|
pub fn default(&self) -> Arc<dyn Config> {
|
||||||
|
@ -86,9 +86,8 @@ impl<'a> espanso_engine::process::MatchFilter for ConfigManager<'a> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let builtin_matches: Vec<i32> = matches_ids
|
let builtin_matches: Vec<i32> = matches_ids
|
||||||
.into_iter()
|
.iter()
|
||||||
.filter(|id| is_builtin_match(**id))
|
.filter(|id| is_builtin_match(**id)).copied()
|
||||||
.map(|id| *id)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut output = active_user_defined_matches;
|
let mut output = active_user_defined_matches;
|
||||||
|
|
|
@ -197,7 +197,7 @@ impl<'a> Drop for ClipboardRestoreGuard<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_combination(combination: &str) -> Option<Vec<Key>> {
|
fn parse_combination(combination: &str) -> Option<Vec<Key>> {
|
||||||
let tokens = combination.split("+");
|
let tokens = combination.split('+');
|
||||||
let mut keys: Vec<Key> = Vec::new();
|
let mut keys: Vec<Key> = Vec::new();
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
keys.push(Key::parse(token)?);
|
keys.push(Key::parse(token)?);
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl<'a> funnel::Source<'a> for DetectSource {
|
||||||
status: convert_to_engine_status(keyboard_event.status),
|
status: convert_to_engine_status(keyboard_event.status),
|
||||||
variant: keyboard_event
|
variant: keyboard_event
|
||||||
.variant
|
.variant
|
||||||
.map(|variant| convert_to_engine_variant(variant)),
|
.map(convert_to_engine_variant),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
InputEvent::Mouse(mouse_event) => Event {
|
InputEvent::Mouse(mouse_event) => Event {
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<'a> MatchSelectorAdapter<'a> {
|
||||||
|
|
||||||
impl<'a> MatchSelector for MatchSelectorAdapter<'a> {
|
impl<'a> MatchSelector for MatchSelectorAdapter<'a> {
|
||||||
fn select(&self, matches_ids: &[i32], is_search: bool) -> Option<i32> {
|
fn select(&self, matches_ids: &[i32], is_search: bool) -> Option<i32> {
|
||||||
let matches = self.match_provider.get_matches(&matches_ids);
|
let matches = self.match_provider.get_matches(matches_ids);
|
||||||
let search_items: Vec<SearchItem> = matches
|
let search_items: Vec<SearchItem> = matches
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
|
|
|
@ -64,7 +64,7 @@ impl<'a> MatchConverter<'a> {
|
||||||
for trigger in cause.triggers.iter() {
|
for trigger in cause.triggers.iter() {
|
||||||
matches.push(RollingMatch::from_string(
|
matches.push(RollingMatch::from_string(
|
||||||
m.id,
|
m.id,
|
||||||
&trigger,
|
trigger,
|
||||||
&StringMatchOptions {
|
&StringMatchOptions {
|
||||||
case_insensitive: cause.propagate_case,
|
case_insensitive: cause.propagate_case,
|
||||||
left_word: cause.left_word,
|
left_word: cause.left_word,
|
||||||
|
@ -80,7 +80,7 @@ impl<'a> MatchConverter<'a> {
|
||||||
for trigger in m.triggers.iter() {
|
for trigger in m.triggers.iter() {
|
||||||
matches.push(RollingMatch::from_string(
|
matches.push(RollingMatch::from_string(
|
||||||
m.id,
|
m.id,
|
||||||
&trigger,
|
trigger,
|
||||||
&StringMatchOptions::default(),
|
&StringMatchOptions::default(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ fn convert_fields(fields: &Params) -> HashMap<String, FormField> {
|
||||||
.and_then(|val| val.as_array())
|
.and_then(|val| val.as_array())
|
||||||
.map(|arr| {
|
.map(|arr| {
|
||||||
arr
|
arr
|
||||||
.into_iter()
|
.iter()
|
||||||
.flat_map(|choice| choice.as_string())
|
.flat_map(|choice| choice.as_string())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -95,7 +95,7 @@ fn convert_fields(fields: &Params) -> HashMap<String, FormField> {
|
||||||
.and_then(|val| val.as_array())
|
.and_then(|val| val.as_array())
|
||||||
.map(|arr| {
|
.map(|arr| {
|
||||||
arr
|
arr
|
||||||
.into_iter()
|
.iter()
|
||||||
.flat_map(|choice| choice.as_string())
|
.flat_map(|choice| choice.as_string())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
@ -86,9 +86,7 @@ fn generate_global_vars_map(config_provider: &dyn ConfigProvider) -> HashMap<i32
|
||||||
|
|
||||||
for (_, match_set) in config_provider.configs() {
|
for (_, match_set) in config_provider.configs() {
|
||||||
for var in match_set.global_vars.iter() {
|
for var in match_set.global_vars.iter() {
|
||||||
if !global_vars_map.contains_key(&var.id) {
|
global_vars_map.entry(var.id).or_insert_with(|| convert_var((*var).clone()));
|
||||||
global_vars_map.insert(var.id, convert_var((*var).clone()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ pub fn initialize_and_spawn(runtime_dir: &Path, exit_notify: Sender<ExitMode>) -
|
||||||
|
|
||||||
EventHandlerResponse::NoResponse
|
EventHandlerResponse::NoResponse
|
||||||
}
|
}
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
unexpected_event => {
|
unexpected_event => {
|
||||||
warn!(
|
warn!(
|
||||||
"received unexpected event in worker ipc handler: {:?}",
|
"received unexpected event in worker ipc handler: {:?}",
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl<'a> super::engine::process::middleware::render::MatchProvider<'a> for Match
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, id: i32) -> Option<&'a Match> {
|
fn get(&self, id: i32) -> Option<&'a Match> {
|
||||||
self.cache.get(&id).map(|m| *m)
|
self.cache.get(&id).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,11 +104,11 @@ impl<'a> CombinedMatchCache<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, match_id: i32) -> Option<MatchVariant<'a>> {
|
pub fn get(&self, match_id: i32) -> Option<MatchVariant<'a>> {
|
||||||
if let Some(user_match) = self.user_match_cache.cache.get(&match_id).map(|m| *m) {
|
if let Some(user_match) = self.user_match_cache.cache.get(&match_id).copied() {
|
||||||
return Some(MatchVariant::User(user_match));
|
return Some(MatchVariant::User(user_match));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(builtin_match) = self.builtin_match_cache.get(&match_id).map(|m| *m) {
|
if let Some(builtin_match) = self.builtin_match_cache.get(&match_id).copied() {
|
||||||
return Some(MatchVariant::Builtin(builtin_match));
|
return Some(MatchVariant::Builtin(builtin_match));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ fn worker_main(args: CliModuleArgs) -> i32 {
|
||||||
// This is needed to avoid "dangling" worker processes
|
// This is needed to avoid "dangling" worker processes
|
||||||
// if the daemon crashes or is forcefully terminated.
|
// if the daemon crashes or is forcefully terminated.
|
||||||
if cli_args.is_present("monitor-daemon") {
|
if cli_args.is_present("monitor-daemon") {
|
||||||
daemon_monitor::initialize_and_spawn(&paths.runtime, engine_exit_notify.clone())
|
daemon_monitor::initialize_and_spawn(&paths.runtime, engine_exit_notify)
|
||||||
.expect("unable to initialize daemon monitor thread");
|
.expect("unable to initialize daemon monitor thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,20 +159,20 @@ fn worker_main(args: CliModuleArgs) -> i32 {
|
||||||
Ok(mode) => match mode {
|
Ok(mode) => match mode {
|
||||||
ExitMode::Exit => {
|
ExitMode::Exit => {
|
||||||
info!("exiting worker process...");
|
info!("exiting worker process...");
|
||||||
return WORKER_SUCCESS;
|
WORKER_SUCCESS
|
||||||
}
|
}
|
||||||
ExitMode::ExitAllProcesses => {
|
ExitMode::ExitAllProcesses => {
|
||||||
info!("exiting worker process and daemon...");
|
info!("exiting worker process and daemon...");
|
||||||
return WORKER_EXIT_ALL_PROCESSES;
|
WORKER_EXIT_ALL_PROCESSES
|
||||||
}
|
}
|
||||||
ExitMode::RestartWorker => {
|
ExitMode::RestartWorker => {
|
||||||
info!("exiting worker (to be restarted)");
|
info!("exiting worker (to be restarted)");
|
||||||
return WORKER_RESTART;
|
WORKER_RESTART
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("unable to read engine exit mode: {:?}", err);
|
error!("unable to read engine exit mode: {:?}", err);
|
||||||
return WORKER_GENERAL_ERROR;
|
WORKER_GENERAL_ERROR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,10 @@
|
||||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossbeam::channel::Sender;
|
use crossbeam::channel::Sender;
|
||||||
use log::{error, info};
|
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum SecureInputEvent {
|
pub enum SecureInputEvent {
|
||||||
Disabled,
|
Disabled,
|
||||||
Enabled { app_name: String, app_path: String },
|
Enabled { app_name: String, app_path: String },
|
||||||
|
@ -36,6 +34,9 @@ pub fn initialize_and_spawn(_secure_input_send: Sender<SecureInputEvent>) -> Res
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn initialize_and_spawn(secure_input_sender: Sender<SecureInputEvent>) -> Result<()> {
|
pub fn initialize_and_spawn(secure_input_sender: Sender<SecureInputEvent>) -> Result<()> {
|
||||||
|
use log::{error, info};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
std::thread::Builder::new()
|
std::thread::Builder::new()
|
||||||
.name("secure-input-monitor".to_string())
|
.name("secure-input-monitor".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
|
|
|
@ -79,8 +79,8 @@ pub struct ConfigLoadResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_config(config_path: &Path, packages_path: &Path) -> Result<ConfigLoadResult> {
|
pub fn load_config(config_path: &Path, packages_path: &Path) -> Result<ConfigLoadResult> {
|
||||||
if espanso_config::is_legacy_config(&config_path) {
|
if espanso_config::is_legacy_config(config_path) {
|
||||||
let (config_store, match_store) = espanso_config::load_legacy(&config_path, &packages_path)
|
let (config_store, match_store) = espanso_config::load_legacy(config_path, packages_path)
|
||||||
.context("unable to load legacy config")?;
|
.context("unable to load legacy config")?;
|
||||||
|
|
||||||
Ok(ConfigLoadResult {
|
Ok(ConfigLoadResult {
|
||||||
|
@ -92,7 +92,7 @@ pub fn load_config(config_path: &Path, packages_path: &Path) -> Result<ConfigLoa
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let (config_store, match_store, non_fatal_errors) =
|
let (config_store, match_store, non_fatal_errors) =
|
||||||
espanso_config::load(&config_path).context("unable to load config")?;
|
espanso_config::load(config_path).context("unable to load config")?;
|
||||||
|
|
||||||
// TODO: add an option to avoid dumping the errors in the logs
|
// TODO: add an option to avoid dumping the errors in the logs
|
||||||
if !non_fatal_errors.is_empty() {
|
if !non_fatal_errors.is_empty() {
|
||||||
|
|
|
@ -52,10 +52,13 @@ pub const SERVICE_ALREADY_RUNNING: i32 = 3;
|
||||||
pub const SERVICE_NOT_RUNNING: i32 = 4;
|
pub const SERVICE_NOT_RUNNING: i32 = 4;
|
||||||
|
|
||||||
pub const WORKAROUND_SUCCESS: i32 = 0;
|
pub const WORKAROUND_SUCCESS: i32 = 0;
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const WORKAROUND_FAILURE: i32 = 1;
|
pub const WORKAROUND_FAILURE: i32 = 1;
|
||||||
pub const WORKAROUND_NOT_AVAILABLE: i32 = 2;
|
pub const WORKAROUND_NOT_AVAILABLE: i32 = 2;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const PACKAGE_SUCCESS: i32 = 0;
|
pub const PACKAGE_SUCCESS: i32 = 0;
|
||||||
|
#[allow(dead_code)]
|
||||||
pub const PACKAGE_UNEXPECTED_FAILURE: i32 = 1;
|
pub const PACKAGE_UNEXPECTED_FAILURE: i32 = 1;
|
||||||
pub const PACKAGE_INSTALL_FAILED: i32 = 2;
|
pub const PACKAGE_INSTALL_FAILED: i32 = 2;
|
||||||
pub const PACKAGE_UNINSTALL_FAILED: i32 = 3;
|
pub const PACKAGE_UNINSTALL_FAILED: i32 = 3;
|
||||||
|
|
|
@ -57,13 +57,13 @@ impl<'a> FormUI for ModuloFormUI<'a> {
|
||||||
match json {
|
match json {
|
||||||
Ok(json) => {
|
Ok(json) => {
|
||||||
if json.is_empty() {
|
if json.is_empty() {
|
||||||
return Ok(None);
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
return Ok(Some(json));
|
Ok(Some(json))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(error.into());
|
Err(error.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'a> SearchUI for ModuloSearchUI<'a> {
|
||||||
let modulo_config = ModuloSearchConfig {
|
let modulo_config = ModuloSearchConfig {
|
||||||
title: "espanso",
|
title: "espanso",
|
||||||
hint,
|
hint,
|
||||||
items: convert_items(&items),
|
items: convert_items(items),
|
||||||
};
|
};
|
||||||
|
|
||||||
let json_config = serde_json::to_string(&modulo_config)?;
|
let json_config = serde_json::to_string(&modulo_config)?;
|
||||||
|
@ -53,13 +53,13 @@ impl<'a> SearchUI for ModuloSearchUI<'a> {
|
||||||
match json {
|
match json {
|
||||||
Ok(json) => {
|
Ok(json) => {
|
||||||
if let Some(Value::String(selected_id)) = json.get("selected") {
|
if let Some(Value::String(selected_id)) = json.get("selected") {
|
||||||
return Ok(Some(selected_id.clone()));
|
Ok(Some(selected_id.clone()))
|
||||||
} else {
|
} else {
|
||||||
return Ok(None);
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(error.into());
|
Err(error.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ struct ModuloSearchItemConfig<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test
|
// TODO: test
|
||||||
fn convert_items<'a>(items: &'a [SearchItem]) -> Vec<ModuloSearchItemConfig<'a>> {
|
fn convert_items(items: &[SearchItem]) -> Vec<ModuloSearchItemConfig> {
|
||||||
items.iter().map(|item| ModuloSearchItemConfig {
|
items.iter().map(|item| ModuloSearchItemConfig {
|
||||||
id: &item.id,
|
id: &item.id,
|
||||||
label: &item.label,
|
label: &item.label,
|
||||||
|
|
|
@ -113,10 +113,10 @@ fn extract_icon(data: &[u8], target_file: &Path) -> Result<PathBuf> {
|
||||||
"skipping extraction for '{:?}', as it's already present",
|
"skipping extraction for '{:?}', as it's already present",
|
||||||
target_file
|
target_file
|
||||||
);
|
);
|
||||||
Ok(target_file.to_owned())
|
|
||||||
} else {
|
} else {
|
||||||
std::fs::write(target_file, data)?;
|
std::fs::write(target_file, data)?;
|
||||||
info!("extracted icon to: {:?}", target_file);
|
info!("extracted icon to: {:?}", target_file);
|
||||||
Ok(target_file.to_owned())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(target_file.to_owned())
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub struct Lock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lock {
|
impl Lock {
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn release(self) -> Result<()> {
|
pub fn release(self) -> Result<()> {
|
||||||
self.lock_file.unlock()?;
|
self.lock_file.unlock()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -41,10 +42,8 @@ impl Lock {
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(&lock_file_path)
|
.open(&lock_file_path)
|
||||||
.expect(&format!(
|
.unwrap_or_else(|_| panic!("unable to create reference to lock file: {:?}",
|
||||||
"unable to create reference to lock file: {:?}",
|
lock_file_path));
|
||||||
lock_file_path
|
|
||||||
));
|
|
||||||
|
|
||||||
if lock_file.try_lock_exclusive().is_ok() {
|
if lock_file.try_lock_exclusive().is_ok() {
|
||||||
Some(Lock { lock_file })
|
Some(Lock { lock_file })
|
||||||
|
@ -59,7 +58,7 @@ impl Drop for Lock {
|
||||||
self
|
self
|
||||||
.lock_file
|
.lock_file
|
||||||
.unlock()
|
.unlock()
|
||||||
.expect(&format!("unable to unlock lock_file: {:?}", self.lock_file));
|
.unwrap_or_else(|_| panic!("unable to unlock lock_file: {:?}", self.lock_file));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,11 +48,9 @@ impl FileProxy {
|
||||||
|
|
||||||
pub fn set_output_file(&self, path: &Path, read_only: bool, create_new: bool) -> Result<()> {
|
pub fn set_output_file(&self, path: &Path, read_only: bool, create_new: bool) -> Result<()> {
|
||||||
// Remove previous log, if present
|
// Remove previous log, if present
|
||||||
if create_new && !read_only {
|
if create_new && !read_only && path.is_file() {
|
||||||
if path.is_file() {
|
|
||||||
std::fs::remove_file(path)?;
|
std::fs::remove_file(path)?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let mut log_file = OpenOptions::new()
|
let mut log_file = OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
|
@ -64,7 +62,7 @@ impl FileProxy {
|
||||||
|
|
||||||
// Transfer the log content that has been buffered into the file
|
// Transfer the log content that has been buffered into the file
|
||||||
if let Output::Memory(buffered) = &mut (*lock) {
|
if let Output::Memory(buffered) = &mut (*lock) {
|
||||||
log_file.write_all(&buffered)?;
|
log_file.write_all(buffered)?;
|
||||||
buffered.clear();
|
buffered.clear();
|
||||||
}
|
}
|
||||||
*lock = Output::File(log_file);
|
*lock = Output::File(log_file);
|
||||||
|
|
|
@ -434,7 +434,7 @@ fn main() {
|
||||||
let mut handler = if let Some(alias) = alias {
|
let mut handler = if let Some(alias) = alias {
|
||||||
CLI_HANDLERS
|
CLI_HANDLERS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|cli| &cli.subcommand == &alias.forward_into)
|
.find(|cli| cli.subcommand == alias.forward_into)
|
||||||
} else {
|
} else {
|
||||||
CLI_HANDLERS
|
CLI_HANDLERS
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -480,7 +480,7 @@ fn main() {
|
||||||
if !handler.disable_logs_terminal_output {
|
if !handler.disable_logs_terminal_output {
|
||||||
outputs.insert(
|
outputs.insert(
|
||||||
0,
|
0,
|
||||||
TermLogger::new(log_level, config.clone(), TerminalMode::Mixed),
|
TermLogger::new(log_level, config, TerminalMode::Mixed),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ fn get_path_override(matches: &ArgMatches, argument: &str, env_var: &str) -> Opt
|
||||||
if let Some(path) = matches.value_of(argument) {
|
if let Some(path) = matches.value_of(argument) {
|
||||||
let path = PathBuf::from(path.trim());
|
let path = PathBuf::from(path.trim());
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
return Some(path);
|
Some(path)
|
||||||
} else {
|
} else {
|
||||||
error_eprintln!("{} argument was specified, but it doesn't point to a valid directory. Make sure to create it first.", argument);
|
error_eprintln!("{} argument was specified, but it doesn't point to a valid directory. Make sure to create it first.", argument);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
@ -588,7 +588,7 @@ fn get_path_override(matches: &ArgMatches, argument: &str, env_var: &str) -> Opt
|
||||||
} else if let Ok(path) = std::env::var(env_var) {
|
} else if let Ok(path) = std::env::var(env_var) {
|
||||||
let path = PathBuf::from(path.trim());
|
let path = PathBuf::from(path.trim());
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
return Some(path);
|
Some(path)
|
||||||
} else {
|
} else {
|
||||||
error_eprintln!("{} env variable was specified, but it doesn't point to a valid directory. Make sure to create it first.", env_var);
|
error_eprintln!("{} env variable was specified, but it doesn't point to a valid directory. Make sure to create it first.", env_var);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::patch::PatchDefinition;
|
||||||
|
|
||||||
pub fn patch() -> PatchDefinition {
|
pub fn patch() -> PatchDefinition {
|
||||||
PatchDefinition {
|
PatchDefinition {
|
||||||
name: module_path!().split(":").last().unwrap_or("unknown"),
|
name: module_path!().split(':').last().unwrap_or("unknown"),
|
||||||
is_enabled: || cfg!(target_os = "windows"),
|
is_enabled: || cfg!(target_os = "windows"),
|
||||||
should_patch: |app| app.title.unwrap_or_default().contains("OneNote"),
|
should_patch: |app| app.title.unwrap_or_default().contains("OneNote"),
|
||||||
apply: |base, name| {
|
apply: |base, name| {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::patch::PatchDefinition;
|
||||||
|
|
||||||
pub fn patch() -> PatchDefinition {
|
pub fn patch() -> PatchDefinition {
|
||||||
PatchDefinition {
|
PatchDefinition {
|
||||||
name: module_path!().split(":").last().unwrap_or("unknown"),
|
name: module_path!().split(':').last().unwrap_or("unknown"),
|
||||||
is_enabled: || cfg!(target_os = "windows"),
|
is_enabled: || cfg!(target_os = "windows"),
|
||||||
should_patch: |app| app.exec.unwrap_or_default().contains("Code.exe"),
|
should_patch: |app| app.exec.unwrap_or_default().contains("Code.exe"),
|
||||||
apply: |base, name| {
|
apply: |base, name| {
|
||||||
|
|
|
@ -61,7 +61,7 @@ fn read_user_path_value() -> Result<String> {
|
||||||
|
|
||||||
fn read_paths() -> Vec<String> {
|
fn read_paths() -> Vec<String> {
|
||||||
let path_value = read_user_path_value().unwrap_or_default();
|
let path_value = read_user_path_value().unwrap_or_default();
|
||||||
let paths = path_value.split(";");
|
let paths = path_value.split(';');
|
||||||
paths.map(String::from).collect()
|
paths.map(String::from).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,18 +40,17 @@ impl<KVSType: KVS> DefaultPreferences<KVSType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get<T: DeserializeOwned>(&self, key: &str) -> Option<T> {
|
fn get<T: DeserializeOwned>(&self, key: &str) -> Option<T> {
|
||||||
let value = self
|
self
|
||||||
.kvs
|
.kvs
|
||||||
.get(key)
|
.get(key)
|
||||||
.expect(&format!("unable to read preference for key {}", key));
|
.unwrap_or_else(|_| panic!("unable to read preference for key {}", key))
|
||||||
value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set<T: Serialize>(&self, key: &str, value: T) {
|
fn set<T: Serialize>(&self, key: &str, value: T) {
|
||||||
self
|
self
|
||||||
.kvs
|
.kvs
|
||||||
.set(key, value)
|
.set(key, value)
|
||||||
.expect(&format!("unable to write preference for key {}", key))
|
.unwrap_or_else(|_| panic!("unable to write preference for key {}", key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user