diff --git a/espanso-config/src/config/mod.rs b/espanso-config/src/config/mod.rs index 3411da5..784c8b3 100644 --- a/espanso-config/src/config/mod.rs +++ b/espanso-config/src/config/mod.rs @@ -19,6 +19,7 @@ use anyhow::Result; use std::{collections::HashSet, path::Path}; +use std::sync::Arc; use thiserror::Error; mod parse; @@ -33,7 +34,7 @@ use mockall::{automock, predicate::*}; use crate::error::NonFatalErrorSet; #[cfg_attr(test, automock)] -pub trait Config: Send { +pub trait Config: Send + Sync { fn id(&self) -> i32; fn label(&self) -> &str; fn match_paths(&self) -> &[String]; @@ -106,9 +107,9 @@ pub trait Config: Send { } pub trait ConfigStore: Send { - fn default(&self) -> &dyn Config; - fn active<'a>(&'a self, app: &AppProperties) -> &'a dyn Config; - fn configs(&self) -> Vec<&dyn Config>; + fn default(&self) -> Arc; + fn active<'a>(&'a self, app: &AppProperties) -> Arc; + fn configs(&self) -> Vec>; fn get_all_match_paths(&self) -> HashSet; } diff --git a/espanso-config/src/config/store.rs b/espanso-config/src/config/store.rs index 654fd8f..bd6d78f 100644 --- a/espanso-config/src/config/store.rs +++ b/espanso-config/src/config/store.rs @@ -23,33 +23,34 @@ use super::{resolve::ResolvedConfig, Config, ConfigStore, ConfigStoreError}; use anyhow::{Context, Result}; use log::{debug, error}; use std::{collections::HashSet, path::Path}; +use std::sync::Arc; pub(crate) struct DefaultConfigStore { - default: Box, - customs: Vec>, + default: Arc, + customs: Vec>, } impl ConfigStore for DefaultConfigStore { - fn default(&self) -> &dyn super::Config { - self.default.as_ref() + fn default(&self) -> Arc { + Arc::clone(&self.default) } - fn active<'a>(&'a self, app: &super::AppProperties) -> &'a dyn super::Config { + fn active<'a>(&'a self, app: &super::AppProperties) -> Arc { // Find a custom config that matches or fallback to the default one for custom in self.customs.iter() { if custom.is_match(app) { - return custom.as_ref(); + return Arc::clone(&custom); } } - self.default.as_ref() + Arc::clone(&self.default) } - fn configs(&self) -> Vec<&dyn Config> { + fn configs(&self) -> Vec> { let mut configs = Vec::new(); - configs.push(self.default.as_ref()); + configs.push(Arc::clone(&self.default)); for custom in self.customs.iter() { - configs.push(custom.as_ref()); + configs.push(Arc::clone(&custom)); } configs @@ -87,7 +88,7 @@ impl DefaultConfigStore { debug!("loaded default config at path: {:?}", default_file); // Then the others - let mut customs: Vec> = Vec::new(); + let mut customs: Vec> = Vec::new(); for entry in std::fs::read_dir(config_dir).map_err(ConfigStoreError::IOError)? { let entry = entry?; let config_file = entry.path(); @@ -104,7 +105,7 @@ impl DefaultConfigStore { { match ResolvedConfig::load(&config_file, Some(&default)) { Ok(config) => { - customs.push(Box::new(config)); + customs.push(Arc::new(config)); debug!("loaded config at path: {:?}", config_file); } Err(err) => { @@ -120,14 +121,14 @@ impl DefaultConfigStore { Ok(( Self { - default: Box::new(default), + default: Arc::new(default), customs, }, non_fatal_errors, )) } - pub fn from_configs(default: Box, customs: Vec>) -> Result { + pub fn from_configs(default: Arc, customs: Vec>) -> Result { Ok(Self { default, customs }) } } @@ -153,8 +154,8 @@ mod tests { let custom2 = new_mock("custom2", true); let store = DefaultConfigStore { - default: Box::new(default), - customs: vec![Box::new(custom1), Box::new(custom2)], + default: Arc::new(default), + customs: vec![Arc::new(custom1), Arc::new(custom2)], }; assert_eq!(store.default().label(), "default"); @@ -177,8 +178,8 @@ mod tests { let custom2 = new_mock("custom2", false); let store = DefaultConfigStore { - default: Box::new(default), - customs: vec![Box::new(custom1), Box::new(custom2)], + default: Arc::new(default), + customs: vec![Arc::new(custom1), Arc::new(custom2)], }; assert_eq!(store.default().label(), "default"); diff --git a/espanso-config/src/legacy/mod.rs b/espanso-config/src/legacy/mod.rs index d33b9b6..5d43bdf 100644 --- a/espanso-config/src/legacy/mod.rs +++ b/espanso-config/src/legacy/mod.rs @@ -20,7 +20,7 @@ use anyhow::Result; use log::warn; use regex::Regex; -use std::{collections::HashMap, path::Path}; +use std::{collections::HashMap, path::Path, sync::Arc}; use self::config::LegacyConfig; use crate::matches::{MatchEffect, group::loader::yaml::{parse::{YAMLMatch, YAMLVariable}, try_convert_into_match, try_convert_into_variable}}; @@ -58,7 +58,7 @@ pub fn load( let mut match_groups = HashMap::new(); match_groups.insert("default".to_string(), default_match_group); - let mut custom_configs: Vec> = Vec::new(); + let mut custom_configs: Vec> = Vec::new(); for custom in config_set.specific { let (custom_config, mut custom_match_group) = split_config(custom); deduplicate_ids( @@ -68,10 +68,10 @@ pub fn load( ); match_groups.insert(custom_config.name.clone(), custom_match_group); - custom_configs.push(Box::new(custom_config)); + custom_configs.push(Arc::new(custom_config)); } - let config_store = DefaultConfigStore::from_configs(Box::new(default_config), custom_configs)?; + let config_store = DefaultConfigStore::from_configs(Arc::new(default_config), custom_configs)?; let match_store = LegacyMatchStore::new(match_groups); Ok((Box::new(config_store), Box::new(match_store)))