feat(core): first draft of builtin matches
This commit is contained in:
parent
90db84b92f
commit
48d05a3f32
38
espanso/src/cli/worker/builtin/debug.rs
Normal file
38
espanso/src/cli/worker/builtin/debug.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This file is part of espanso.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Federico Terzi
|
||||
*
|
||||
* espanso is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* espanso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::{cli::worker::builtin::generate_next_builtin_id, engine::event::{EventType, effect::TextInjectRequest}};
|
||||
|
||||
use super::BuiltInMatch;
|
||||
|
||||
pub fn create_match_show_active_config_info() -> BuiltInMatch {
|
||||
BuiltInMatch {
|
||||
id: generate_next_builtin_id(),
|
||||
label: "Display active config information",
|
||||
triggers: vec!["#acfg#".to_string()],
|
||||
action: |context| {
|
||||
println!("active config: {:?}", context.get_active_config().label());
|
||||
|
||||
EventType::TextInject(TextInjectRequest {
|
||||
text: "test".to_string(),
|
||||
force_mode: None,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
57
espanso/src/cli/worker/builtin/mod.rs
Normal file
57
espanso/src/cli/worker/builtin/mod.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of espanso.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Federico Terzi
|
||||
*
|
||||
* espanso is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* espanso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use crate::engine::event::EventType;
|
||||
|
||||
use super::context::Context;
|
||||
|
||||
mod debug;
|
||||
|
||||
const MIN_BUILTIN_MATCH_ID: i32 = 1_000_000_000;
|
||||
|
||||
pub struct BuiltInMatch {
|
||||
pub id: i32,
|
||||
pub label: &'static str,
|
||||
pub triggers: Vec<String>,
|
||||
pub action: fn(context: &dyn Context) -> EventType,
|
||||
}
|
||||
|
||||
pub fn get_builtin_matches() -> Vec<BuiltInMatch> {
|
||||
vec![
|
||||
debug::create_match_show_active_config_info(),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn is_builtin_match(id: i32) -> bool {
|
||||
id >= MIN_BUILTIN_MATCH_ID
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CURRENT_BUILTIN_MATCH_ID: Cell<i32> = Cell::new(MIN_BUILTIN_MATCH_ID);
|
||||
}
|
||||
|
||||
fn generate_next_builtin_id() -> i32 {
|
||||
CURRENT_BUILTIN_MATCH_ID.with(|value| {
|
||||
let current = value.get();
|
||||
value.set(current + 1);
|
||||
current
|
||||
})
|
||||
}
|
|
@ -26,6 +26,8 @@ use espanso_config::{
|
|||
use espanso_info::{AppInfo, AppInfoProvider};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use super::builtin::is_builtin_match;
|
||||
|
||||
pub struct ConfigManager<'a> {
|
||||
config_store: &'a dyn ConfigStore,
|
||||
match_store: &'a dyn MatchStore,
|
||||
|
@ -57,7 +59,7 @@ impl<'a> ConfigManager<'a> {
|
|||
(config.clone(), self.match_store.query(&match_paths))
|
||||
}
|
||||
|
||||
pub fn default(&self) -> Arc<dyn Config>{
|
||||
pub fn default(&self) -> Arc<dyn Config> {
|
||||
self.config_store.default()
|
||||
}
|
||||
}
|
||||
|
@ -76,12 +78,22 @@ impl<'a> crate::engine::process::MatchFilter for ConfigManager<'a> {
|
|||
let ids_set: HashSet<i32> = HashSet::from_iter(matches_ids.iter().copied());
|
||||
let (_, match_set) = self.active_context();
|
||||
|
||||
match_set
|
||||
let active_user_defined_matches: Vec<i32> = match_set
|
||||
.matches
|
||||
.iter()
|
||||
.filter(|m| ids_set.contains(&m.id))
|
||||
.map(|m| m.id)
|
||||
.collect()
|
||||
.collect();
|
||||
|
||||
let builtin_matches: Vec<i32> = matches_ids
|
||||
.into_iter()
|
||||
.filter(|id| is_builtin_match(**id))
|
||||
.map(|id| *id)
|
||||
.collect();
|
||||
|
||||
let mut output = active_user_defined_matches;
|
||||
output.extend(builtin_matches);
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
|
|
43
espanso/src/cli/worker/context/default.rs
Normal file
43
espanso/src/cli/worker/context/default.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is part of espanso.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Federico Terzi
|
||||
*
|
||||
* espanso is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* espanso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::cli::worker::config::ConfigManager;
|
||||
|
||||
pub struct DefaultContext<'a> {
|
||||
config_manager: &'a ConfigManager<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DefaultContext<'a> {
|
||||
pub fn new(config_manager: &'a ConfigManager<'a>) -> Self {
|
||||
Self { config_manager }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Context for DefaultContext<'a> {}
|
||||
|
||||
impl<'a> ConfigContext for DefaultContext<'a> {
|
||||
fn get_default_config(&self) -> Arc<dyn Config> {
|
||||
self.config_manager.default()
|
||||
}
|
||||
|
||||
fn get_active_config(&self) -> Arc<dyn Config> {
|
||||
self.config_manager.active()
|
||||
}
|
||||
}
|
32
espanso/src/cli/worker/context/mod.rs
Normal file
32
espanso/src/cli/worker/context/mod.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of espanso.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Federico Terzi
|
||||
*
|
||||
* espanso is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* espanso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use espanso_config::config::Config;
|
||||
|
||||
mod default;
|
||||
pub use default::DefaultContext;
|
||||
|
||||
pub trait Context: ConfigContext {}
|
||||
|
||||
pub trait ConfigContext {
|
||||
fn get_default_config(&self) -> Arc<dyn Config>;
|
||||
fn get_active_config(&self) -> Arc<dyn Config>;
|
||||
}
|
|
@ -28,8 +28,7 @@ use espanso_path::Paths;
|
|||
use espanso_ui::{event::UIEvent, UIRemote};
|
||||
use log::{debug, error, info, warn};
|
||||
|
||||
use crate::{cli::worker::{
|
||||
engine::{
|
||||
use crate::{cli::worker::{context::Context, engine::{
|
||||
dispatch::executor::{
|
||||
clipboard_injector::ClipboardInjectorAdapter, context_menu::ContextMenuHandlerAdapter,
|
||||
event_injector::EventInjectorAdapter, icon::IconHandlerAdapter,
|
||||
|
@ -49,9 +48,7 @@ use crate::{cli::worker::{
|
|||
RendererAdapter,
|
||||
},
|
||||
},
|
||||
},
|
||||
match_cache::MatchCache,
|
||||
}, engine::event::ExitMode, preferences::Preferences};
|
||||
}, match_cache::{CombinedMatchCache, MatchCache}}, engine::event::ExitMode, preferences::Preferences};
|
||||
|
||||
use super::secure_input::SecureInputEvent;
|
||||
|
||||
|
@ -82,13 +79,18 @@ pub fn initialize_and_spawn(
|
|||
espanso_info::get_provider().expect("unable to initialize app info provider");
|
||||
let config_manager =
|
||||
super::config::ConfigManager::new(&*config_store, &*match_store, &*app_info_provider);
|
||||
let match_converter = MatchConverter::new(&*config_store, &*match_store);
|
||||
let match_cache = MatchCache::load(&*config_store, &*match_store);
|
||||
|
||||
let modulo_manager = crate::gui::modulo::manager::ModuloManager::new();
|
||||
let modulo_form_ui = crate::gui::modulo::form::ModuloFormUI::new(&modulo_manager);
|
||||
let modulo_search_ui = crate::gui::modulo::search::ModuloSearchUI::new(&modulo_manager);
|
||||
|
||||
let context: Box<dyn Context> = Box::new(super::context::DefaultContext::new(&config_manager));
|
||||
let builtin_matches = super::builtin::get_builtin_matches();
|
||||
let combined_match_cache = CombinedMatchCache::load(&match_cache, &builtin_matches);
|
||||
|
||||
let match_converter = MatchConverter::new(&*config_store, &*match_store, &builtin_matches);
|
||||
|
||||
let has_granted_capabilities = grant_linux_capabilities(use_evdev_backend);
|
||||
|
||||
// TODO: pass all the options
|
||||
|
@ -129,8 +131,8 @@ pub fn initialize_and_spawn(
|
|||
super::engine::process::middleware::matcher::MatcherState,
|
||||
>,
|
||||
> = vec![&rolling_matcher, ®ex_matcher];
|
||||
let selector = MatchSelectorAdapter::new(&modulo_search_ui, &match_cache);
|
||||
let multiplexer = MultiplexAdapter::new(&match_cache);
|
||||
let selector = MatchSelectorAdapter::new(&modulo_search_ui, &combined_match_cache);
|
||||
let multiplexer = MultiplexAdapter::new(&combined_match_cache, &*context);
|
||||
|
||||
let injector = espanso_inject::get_injector(InjectorCreationOptions {
|
||||
use_evdev: use_evdev_backend,
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use espanso_config::matches::{Match};
|
||||
use log::error;
|
||||
|
||||
use crate::{
|
||||
|
@ -28,7 +27,13 @@ use crate::{
|
|||
const MAX_LABEL_LEN: usize = 100;
|
||||
|
||||
pub trait MatchProvider<'a> {
|
||||
fn get_matches(&self, ids: &[i32]) -> Vec<&'a Match>;
|
||||
fn get_matches(&self, ids: &[i32]) -> Vec<MatchSummary<'a>>;
|
||||
}
|
||||
|
||||
pub struct MatchSummary<'a> {
|
||||
pub id: i32,
|
||||
pub label: &'a str,
|
||||
pub tag: Option<&'a str>,
|
||||
}
|
||||
|
||||
pub struct MatchSelectorAdapter<'a> {
|
||||
|
@ -49,15 +54,14 @@ impl<'a> MatchSelector for MatchSelectorAdapter<'a> {
|
|||
fn select(&self, matches_ids: &[i32]) -> Option<i32> {
|
||||
let matches = self.match_provider.get_matches(&matches_ids);
|
||||
let search_items: Vec<SearchItem> = matches
|
||||
.iter()
|
||||
.into_iter()
|
||||
.map(|m| {
|
||||
let label = m.description();
|
||||
let clipped_label = &label[..std::cmp::min(label.len(), MAX_LABEL_LEN)];
|
||||
let clipped_label = &m.label[..std::cmp::min(m.label.len(), MAX_LABEL_LEN)];
|
||||
|
||||
SearchItem {
|
||||
id: m.id.to_string(),
|
||||
label: clipped_label.to_string(),
|
||||
tag: m.cause_description().map(String::from),
|
||||
tag: m.tag.map(String::from),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -30,16 +30,24 @@ use espanso_match::{
|
|||
};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use crate::cli::worker::builtin::BuiltInMatch;
|
||||
|
||||
pub struct MatchConverter<'a> {
|
||||
config_store: &'a dyn ConfigStore,
|
||||
match_store: &'a dyn MatchStore,
|
||||
builtin_matches: &'a [BuiltInMatch],
|
||||
}
|
||||
|
||||
impl<'a> MatchConverter<'a> {
|
||||
pub fn new(config_store: &'a dyn ConfigStore, match_store: &'a dyn MatchStore) -> Self {
|
||||
pub fn new(
|
||||
config_store: &'a dyn ConfigStore,
|
||||
match_store: &'a dyn MatchStore,
|
||||
builtin_matches: &'a [BuiltInMatch],
|
||||
) -> Self {
|
||||
Self {
|
||||
config_store,
|
||||
match_store,
|
||||
builtin_matches,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +56,7 @@ impl<'a> MatchConverter<'a> {
|
|||
let match_set = self.global_match_set();
|
||||
let mut matches = Vec::new();
|
||||
|
||||
// First convert configuration (user-defined) matches
|
||||
for m in match_set.matches {
|
||||
if let MatchCause::Trigger(cause) = &m.cause {
|
||||
for trigger in cause.triggers.iter() {
|
||||
|
@ -64,6 +73,17 @@ impl<'a> MatchConverter<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// Then convert built-in ones
|
||||
for m in self.builtin_matches {
|
||||
for trigger in m.triggers.iter() {
|
||||
matches.push(RollingMatch::from_string(
|
||||
m.id,
|
||||
&trigger,
|
||||
&StringMatchOptions::default()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
matches
|
||||
}
|
||||
|
||||
|
@ -74,10 +94,7 @@ impl<'a> MatchConverter<'a> {
|
|||
|
||||
for m in match_set.matches {
|
||||
if let MatchCause::Regex(cause) = &m.cause {
|
||||
matches.push(RegexMatch::new(
|
||||
m.id,
|
||||
&cause.regex,
|
||||
))
|
||||
matches.push(RegexMatch::new(m.id, &cause.regex))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,40 +19,59 @@
|
|||
|
||||
use espanso_config::matches::{Match, MatchEffect};
|
||||
|
||||
use crate::engine::{event::{EventType, internal::DetectedMatch, internal::{ImageRequestedEvent, RenderingRequestedEvent, TextFormat}}, process::Multiplexer};
|
||||
use crate::{
|
||||
cli::worker::{builtin::BuiltInMatch, context::Context},
|
||||
engine::{
|
||||
event::{
|
||||
internal::DetectedMatch,
|
||||
internal::{ImageRequestedEvent, RenderingRequestedEvent, TextFormat},
|
||||
EventType,
|
||||
},
|
||||
process::Multiplexer,
|
||||
},
|
||||
};
|
||||
|
||||
pub trait MatchProvider<'a> {
|
||||
fn get(&self, match_id: i32) -> Option<&'a Match>;
|
||||
fn get(&self, match_id: i32) -> Option<MatchResult<'a>>;
|
||||
}
|
||||
|
||||
pub enum MatchResult<'a> {
|
||||
User(&'a Match),
|
||||
Builtin(&'a BuiltInMatch),
|
||||
}
|
||||
|
||||
pub struct MultiplexAdapter<'a> {
|
||||
provider: &'a dyn MatchProvider<'a>,
|
||||
context: &'a dyn Context,
|
||||
}
|
||||
|
||||
impl<'a> MultiplexAdapter<'a> {
|
||||
pub fn new(provider: &'a dyn MatchProvider<'a>) -> Self {
|
||||
Self { provider }
|
||||
pub fn new(provider: &'a dyn MatchProvider<'a>, context: &'a dyn Context) -> Self {
|
||||
Self { provider, context }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Multiplexer for MultiplexAdapter<'a> {
|
||||
fn convert(&self, detected_match: DetectedMatch) -> Option<EventType> {
|
||||
let m = self.provider.get(detected_match.id)?;
|
||||
|
||||
match &m.effect {
|
||||
MatchEffect::Text(effect) => Some(EventType::RenderingRequested(RenderingRequestedEvent {
|
||||
match_id: detected_match.id,
|
||||
trigger: detected_match.trigger,
|
||||
left_separator: detected_match.left_separator,
|
||||
right_separator: detected_match.right_separator,
|
||||
trigger_args: detected_match.args,
|
||||
format: convert_format(&effect.format),
|
||||
})),
|
||||
MatchEffect::Image(effect) => Some(EventType::ImageRequested(ImageRequestedEvent {
|
||||
match_id: detected_match.id,
|
||||
image_path: effect.path.clone(),
|
||||
})),
|
||||
MatchEffect::None => None,
|
||||
match self.provider.get(detected_match.id)? {
|
||||
MatchResult::User(m) => match &m.effect {
|
||||
MatchEffect::Text(effect) => Some(EventType::RenderingRequested(RenderingRequestedEvent {
|
||||
match_id: detected_match.id,
|
||||
trigger: detected_match.trigger,
|
||||
left_separator: detected_match.left_separator,
|
||||
right_separator: detected_match.right_separator,
|
||||
trigger_args: detected_match.args,
|
||||
format: convert_format(&effect.format),
|
||||
})),
|
||||
MatchEffect::Image(effect) => Some(EventType::ImageRequested(ImageRequestedEvent {
|
||||
match_id: detected_match.id,
|
||||
image_path: effect.path.clone(),
|
||||
})),
|
||||
MatchEffect::None => None,
|
||||
},
|
||||
MatchResult::Builtin(m) => {
|
||||
Some((m.action)(self.context))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +79,7 @@ impl<'a> Multiplexer for MultiplexAdapter<'a> {
|
|||
fn convert_format(format: &espanso_config::matches::TextFormat) -> TextFormat {
|
||||
match format {
|
||||
espanso_config::matches::TextFormat::Plain => TextFormat::Plain,
|
||||
espanso_config::matches::TextFormat::Markdown => TextFormat::Markdown,
|
||||
espanso_config::matches::TextFormat::Html => TextFormat::Html,
|
||||
espanso_config::matches::TextFormat::Markdown => TextFormat::Markdown,
|
||||
espanso_config::matches::TextFormat::Html => TextFormat::Html,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ use espanso_config::{
|
|||
matches::{store::MatchStore, Match, MatchEffect},
|
||||
};
|
||||
|
||||
use super::{builtin::BuiltInMatch, engine::process::middleware::match_select::MatchSummary};
|
||||
|
||||
pub struct MatchCache<'a> {
|
||||
cache: HashMap<i32, &'a Match>,
|
||||
}
|
||||
|
@ -43,12 +45,6 @@ impl<'a> MatchCache<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> super::engine::process::middleware::multiplex::MatchProvider<'a> for MatchCache<'a> {
|
||||
fn get(&self, match_id: i32) -> Option<&'a Match> {
|
||||
self.cache.get(&match_id).map(|m| *m)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> super::engine::process::middleware::render::MatchProvider<'a> for MatchCache<'a> {
|
||||
fn matches(&self) -> Vec<&'a Match> {
|
||||
self.cache.iter().map(|(_, m)| *m).collect()
|
||||
|
@ -59,15 +55,6 @@ impl<'a> super::engine::process::middleware::render::MatchProvider<'a> for Match
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> super::engine::process::middleware::match_select::MatchProvider<'a> for MatchCache<'a> {
|
||||
fn get_matches(&self, ids: &[i32]) -> Vec<&'a Match> {
|
||||
ids
|
||||
.iter()
|
||||
.flat_map(|id| self.cache.get(&id).map(|m| *m))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::engine::process::MatchInfoProvider for MatchCache<'a> {
|
||||
fn get_force_mode(&self, match_id: i32) -> Option<crate::engine::event::effect::TextInjectMode> {
|
||||
let m = self.cache.get(&match_id)?;
|
||||
|
@ -87,3 +74,79 @@ impl<'a> crate::engine::process::MatchInfoProvider for MatchCache<'a> {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CombinedMatchCache<'a> {
|
||||
user_match_cache: &'a MatchCache<'a>,
|
||||
builtin_match_cache: HashMap<i32, &'a BuiltInMatch>,
|
||||
}
|
||||
|
||||
pub enum MatchVariant<'a> {
|
||||
User(&'a Match),
|
||||
Builtin(&'a BuiltInMatch),
|
||||
}
|
||||
|
||||
impl<'a> CombinedMatchCache<'a> {
|
||||
pub fn load(user_match_cache: &'a MatchCache<'a>, builtin_matches: &'a [BuiltInMatch]) -> Self {
|
||||
let mut builtin_match_cache = HashMap::new();
|
||||
|
||||
for m in builtin_matches {
|
||||
builtin_match_cache.insert(m.id, m);
|
||||
}
|
||||
|
||||
Self {
|
||||
builtin_match_cache,
|
||||
user_match_cache,
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
return Some(MatchVariant::User(user_match));
|
||||
}
|
||||
|
||||
if let Some(builtin_match) = self.builtin_match_cache.get(&match_id).map(|m| *m) {
|
||||
return Some(MatchVariant::Builtin(builtin_match));
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> super::engine::process::middleware::match_select::MatchProvider<'a>
|
||||
for CombinedMatchCache<'a>
|
||||
{
|
||||
fn get_matches(&self, ids: &[i32]) -> Vec<MatchSummary<'a>> {
|
||||
ids
|
||||
.iter()
|
||||
.filter_map(|id| self.get(*id))
|
||||
.map(|m| match m {
|
||||
MatchVariant::User(m) => MatchSummary {
|
||||
id: m.id,
|
||||
label: m.description(),
|
||||
tag: m.cause_description(),
|
||||
},
|
||||
MatchVariant::Builtin(m) => MatchSummary {
|
||||
id: m.id,
|
||||
label: m.label,
|
||||
tag: m.triggers.first().map(String::as_ref),
|
||||
},
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> super::engine::process::middleware::multiplex::MatchProvider<'a>
|
||||
for CombinedMatchCache<'a>
|
||||
{
|
||||
fn get(
|
||||
&self,
|
||||
match_id: i32,
|
||||
) -> Option<super::engine::process::middleware::multiplex::MatchResult<'a>> {
|
||||
Some(match self.get(match_id)? {
|
||||
MatchVariant::User(m) => super::engine::process::middleware::multiplex::MatchResult::User(m),
|
||||
MatchVariant::Builtin(m) => {
|
||||
super::engine::process::middleware::multiplex::MatchResult::Builtin(m)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ use self::ui::util::convert_icon_paths_to_tray_vec;
|
|||
|
||||
use super::{CliModule, CliModuleArgs};
|
||||
|
||||
mod builtin;
|
||||
mod config;
|
||||
mod context;
|
||||
mod daemon_monitor;
|
||||
mod engine;
|
||||
mod ipc;
|
||||
|
|
Loading…
Reference in New Issue
Block a user