Initial draft of config parsing
This commit is contained in:
parent
79a1b85769
commit
e26a04de67
52
Cargo.lock
generated
52
Cargo.lock
generated
|
@ -190,6 +190,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
|
@ -212,6 +218,7 @@ dependencies = [
|
|||
name = "espanso"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"espanso-config",
|
||||
"espanso-detect",
|
||||
"espanso-inject",
|
||||
"espanso-ui",
|
||||
|
@ -219,6 +226,18 @@ dependencies = [
|
|||
"simplelog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "espanso-config"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glob",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "espanso-detect"
|
||||
version = "0.1.0"
|
||||
|
@ -292,6 +311,12 @@ dependencies = [
|
|||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.2"
|
||||
|
@ -343,6 +368,12 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -588,6 +619,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.8.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"linked-hash-map",
|
||||
"serde",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
version = "0.9.0"
|
||||
|
@ -792,3 +835,12 @@ checksum = "e1945e12e16b951721d7976520b0832496ef79c31602c7a29d950de79ba74621"
|
|||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
|
|
@ -6,4 +6,5 @@ members = [
|
|||
"espanso-ui",
|
||||
"espanso-inject",
|
||||
"espanso-ipc",
|
||||
"espanso-config",
|
||||
]
|
13
espanso-config/Cargo.toml
Normal file
13
espanso-config/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "espanso-config"
|
||||
version = "0.1.0"
|
||||
authors = ["Federico Terzi <federico-terzi@users.noreply.github.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.14"
|
||||
anyhow = "1.0.38"
|
||||
thiserror = "1.0.23"
|
||||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
serde_yaml = "0.8.17"
|
||||
glob = "0.3.0"
|
15
espanso-config/src/config/mod.rs
Normal file
15
espanso-config/src/config/mod.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use std::collections::HashSet;
|
||||
use anyhow::Result;
|
||||
|
||||
|
||||
mod yaml;
|
||||
mod path;
|
||||
|
||||
pub struct Config {
|
||||
pub label: Option<String>,
|
||||
//pub backend:
|
||||
pub match_files: Vec<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
}
|
34
espanso-config/src/config/path.rs
Normal file
34
espanso-config/src/config/path.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use glob::glob;
|
||||
use log::error;
|
||||
|
||||
// TODO: test
|
||||
pub fn calculate_paths<'a>(glob_patterns: impl Iterator<Item = &'a String>) -> HashSet<String> {
|
||||
let mut path_set = HashSet::new();
|
||||
for glob_pattern in glob_patterns {
|
||||
let entries = glob(glob_pattern);
|
||||
match entries {
|
||||
Ok(paths) => {
|
||||
for path in paths {
|
||||
match path {
|
||||
Ok(path) => {
|
||||
path_set.insert(path.to_string_lossy().to_string());
|
||||
}
|
||||
Err(err) => {
|
||||
error!("glob error when processing pattern: {}, with error: {}", glob_pattern, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"unable to calculate glob from pattern: {}, with error: {}",
|
||||
glob_pattern, err
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
path_set
|
||||
}
|
89
espanso-config/src/config/yaml.rs
Normal file
89
espanso-config/src/config/yaml.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use std::collections::HashSet;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use super::path::calculate_paths;
|
||||
|
||||
const STANDARD_INCLUDES: &[&str] = &["match/**/*.yml"];
|
||||
const STANDARD_EXCLUDES: &[&str] = &["match/**/_*.yml"];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct YAMLConfig {
|
||||
pub label: Option<String>,
|
||||
|
||||
pub includes: Option<Vec<String>>,
|
||||
|
||||
pub excludes: Option<Vec<String>>,
|
||||
|
||||
pub extra_includes: Option<Vec<String>>,
|
||||
|
||||
pub extra_excludes: Option<Vec<String>>,
|
||||
|
||||
pub use_standard_includes: bool,
|
||||
|
||||
// Filters
|
||||
|
||||
pub filter_title: Option<String>,
|
||||
pub filter_class: Option<String>,
|
||||
pub filter_exec: Option<String>,
|
||||
pub filter_os: Option<String>,
|
||||
}
|
||||
|
||||
impl YAMLConfig {
|
||||
// TODO test
|
||||
pub fn aggregate_includes(&self) -> HashSet<String> {
|
||||
let mut includes = HashSet::new();
|
||||
|
||||
if self.use_standard_includes {
|
||||
STANDARD_INCLUDES.iter().for_each(|include| { includes.insert(include.to_string()); })
|
||||
}
|
||||
|
||||
if let Some(yaml_includes) = self.includes.as_ref() {
|
||||
yaml_includes.iter().for_each(|include| { includes.insert(include.to_string()); })
|
||||
}
|
||||
|
||||
if let Some(extra_includes) = self.extra_includes.as_ref() {
|
||||
extra_includes.iter().for_each(|include| { includes.insert(include.to_string()); })
|
||||
}
|
||||
|
||||
includes
|
||||
}
|
||||
|
||||
// TODO test
|
||||
pub fn aggregate_excludes(&self) -> HashSet<String> {
|
||||
let mut excludes = HashSet::new();
|
||||
|
||||
if self.use_standard_includes {
|
||||
STANDARD_EXCLUDES.iter().for_each(|exclude| { excludes.insert(exclude.to_string()); })
|
||||
}
|
||||
|
||||
if let Some(yaml_excludes) = self.excludes.as_ref() {
|
||||
yaml_excludes.iter().for_each(|exclude| { excludes.insert(exclude.to_string()); })
|
||||
}
|
||||
|
||||
if let Some(extra_excludes) = self.extra_excludes.as_ref() {
|
||||
extra_excludes.iter().for_each(|exclude| { excludes.insert(exclude.to_string()); })
|
||||
}
|
||||
|
||||
excludes
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: convert to TryFrom (check the matches section for an example)
|
||||
impl From<YAMLConfig> for super::Config {
|
||||
// TODO: test
|
||||
fn from(yaml_config: YAMLConfig) -> Self {
|
||||
let includes = yaml_config.aggregate_includes();
|
||||
let excludes = yaml_config.aggregate_excludes();
|
||||
|
||||
// Extract the paths
|
||||
let exclude_paths = calculate_paths(excludes.iter());
|
||||
let include_paths = calculate_paths(includes.iter());
|
||||
|
||||
let match_files: Vec<String> = Vec::from_iter(include_paths.difference(&exclude_paths).cloned());
|
||||
|
||||
Self {
|
||||
label: yaml_config.label,
|
||||
match_files,
|
||||
}
|
||||
}
|
||||
}
|
58
espanso-config/src/lib.rs
Normal file
58
espanso-config/src/lib.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
mod config;
|
||||
mod matches;
|
||||
|
||||
use std::path::Path;
|
||||
use anyhow::Result;
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use thiserror::Error;
|
||||
use config::Config;
|
||||
|
||||
|
||||
pub struct ConfigSet {
|
||||
|
||||
}
|
||||
|
||||
impl ConfigSet {
|
||||
//fn active(&self, app: AppProperties) -> &'a Config {
|
||||
// TODO: using the app properties, check if any of the sub configs match or not. If not, return the default
|
||||
// Here a RegexSet might be very useful to efficiently match them.
|
||||
//}
|
||||
|
||||
//fn default(&self) -> &'a Config {}
|
||||
}
|
||||
|
||||
pub struct AppProperties<'a> {
|
||||
pub title: Option<&'a str>,
|
||||
pub class: Option<&'a str>,
|
||||
pub exec: Option<&'a str>,
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn todo() {
|
||||
|
||||
}
|
||||
}
|
85
espanso-config/src/matches/mod.rs
Normal file
85
espanso-config/src/matches/mod.rs
Normal file
|
@ -0,0 +1,85 @@
|
|||
use serde_yaml::Mapping;
|
||||
|
||||
mod yaml;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Match {
|
||||
cause: MatchCause,
|
||||
effect: MatchEffect,
|
||||
|
||||
// Metadata
|
||||
label: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for Match {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cause: MatchCause::None,
|
||||
effect: MatchEffect::None,
|
||||
label: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Causes
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum MatchCause {
|
||||
None,
|
||||
Trigger(TriggerCause),
|
||||
// TODO: regex
|
||||
// TODO: shortcut
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TriggerCause {
|
||||
pub triggers: Vec<String>,
|
||||
|
||||
pub left_word: bool,
|
||||
pub right_word: bool,
|
||||
|
||||
pub propagate_case: bool,
|
||||
}
|
||||
|
||||
impl Default for TriggerCause {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
triggers: Vec::new(),
|
||||
left_word: false,
|
||||
right_word: false,
|
||||
propagate_case: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Effects
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum MatchEffect {
|
||||
None,
|
||||
Text(TextEffect),
|
||||
// TODO: image
|
||||
// TODO: rich text
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TextEffect {
|
||||
pub replace: String,
|
||||
pub vars: Vec<Variable>,
|
||||
}
|
||||
|
||||
impl Default for TextEffect {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
replace: String::new(),
|
||||
vars: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Variable {
|
||||
pub name: String,
|
||||
pub var_type: String,
|
||||
pub params: Mapping,
|
||||
}
|
384
espanso-config/src/matches/yaml.rs
Normal file
384
espanso-config/src/matches/yaml.rs
Normal file
|
@ -0,0 +1,384 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
convert::{TryFrom, TryInto},
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use thiserror::Error;
|
||||
|
||||
use super::{MatchCause, MatchEffect, TextEffect, TriggerCause, Variable};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
struct YAMLMatch {
|
||||
#[serde(default)]
|
||||
pub trigger: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub triggers: Option<Vec<String>>,
|
||||
|
||||
#[serde(default)]
|
||||
pub replace: Option<String>,
|
||||
|
||||
#[serde(default)]
|
||||
pub image_path: Option<String>, // TODO: map
|
||||
|
||||
#[serde(default)]
|
||||
pub form: Option<String>, // TODO: map
|
||||
|
||||
#[serde(default)]
|
||||
pub form_fields: Option<HashMap<String, Value>>, // TODO: map
|
||||
|
||||
#[serde(default)]
|
||||
pub vars: Option<Vec<YAMLVariable>>,
|
||||
|
||||
#[serde(default)]
|
||||
pub word: Option<bool>,
|
||||
|
||||
#[serde(default)]
|
||||
pub left_word: Option<bool>,
|
||||
|
||||
#[serde(default)]
|
||||
pub right_word: Option<bool>,
|
||||
|
||||
#[serde(default)]
|
||||
pub propagate_case: Option<bool>,
|
||||
|
||||
#[serde(default)]
|
||||
pub force_clipboard: Option<bool>,
|
||||
|
||||
#[serde(default)]
|
||||
pub markdown: Option<String>, // TODO: map
|
||||
|
||||
#[serde(default)]
|
||||
pub paragraph: Option<bool>, // TODO: map
|
||||
|
||||
#[serde(default)]
|
||||
pub html: Option<String>, // TODO: map
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
pub struct YAMLVariable {
|
||||
pub name: String,
|
||||
|
||||
#[serde(rename = "type")]
|
||||
pub var_type: String,
|
||||
|
||||
#[serde(default = "default_params")]
|
||||
pub params: Mapping,
|
||||
}
|
||||
|
||||
fn default_params() -> Mapping {
|
||||
Mapping::new()
|
||||
}
|
||||
|
||||
impl TryFrom<YAMLMatch> for super::Match {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
// TODO: test
|
||||
fn try_from(yaml_match: YAMLMatch) -> Result<Self, Self::Error> {
|
||||
let triggers = if let Some(trigger) = yaml_match.trigger {
|
||||
Some(vec![trigger])
|
||||
} else if let Some(triggers) = yaml_match.triggers {
|
||||
Some(triggers)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let cause = if let Some(triggers) = triggers {
|
||||
MatchCause::Trigger(TriggerCause {
|
||||
triggers,
|
||||
left_word: yaml_match
|
||||
.left_word
|
||||
.or(yaml_match.word)
|
||||
.unwrap_or(TriggerCause::default().left_word),
|
||||
right_word: yaml_match
|
||||
.right_word
|
||||
.or(yaml_match.word)
|
||||
.unwrap_or(TriggerCause::default().right_word),
|
||||
propagate_case: yaml_match
|
||||
.propagate_case
|
||||
.unwrap_or(TriggerCause::default().propagate_case),
|
||||
})
|
||||
} else {
|
||||
MatchCause::None
|
||||
};
|
||||
|
||||
let effect = if let Some(replace) = yaml_match.replace {
|
||||
let vars: Result<Vec<Variable>> = yaml_match
|
||||
.vars
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|var| var.try_into())
|
||||
.collect();
|
||||
MatchEffect::Text(TextEffect {
|
||||
replace,
|
||||
vars: vars?,
|
||||
})
|
||||
} else {
|
||||
MatchEffect::None
|
||||
};
|
||||
|
||||
// TODO: log none match effect
|
||||
|
||||
Ok(Self {
|
||||
cause,
|
||||
effect,
|
||||
label: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<YAMLVariable> for super::Variable {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
// TODO: test
|
||||
fn try_from(yaml_var: YAMLVariable) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
name: yaml_var.name,
|
||||
var_type: yaml_var.var_type,
|
||||
params: yaml_var.params,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum YAMLConversionError {
|
||||
// TODO
|
||||
//#[error("unknown data store error")]
|
||||
//Unknown,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::matches::Match;
|
||||
|
||||
fn create_match(yaml: &str) -> Result<Match> {
|
||||
let yaml_match: YAMLMatch = serde_yaml::from_str(yaml)?;
|
||||
let m: Match = yaml_match.try_into()?;
|
||||
Ok(m)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_match_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_triggers_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
triggers: ["Hello", "john"]
|
||||
replace: "world"
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string(), "john".to_string()],
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn word_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
word: true
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
left_word: true,
|
||||
right_word: true,
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn left_word_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
left_word: true
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
left_word: true,
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn right_word_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
right_word: true
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
right_word: true,
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn propagate_case_maps_correctly() {
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
propagate_case: true
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
propagate_case: true,
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vars_maps_correctly() {
|
||||
let mut params = Mapping::new();
|
||||
params.insert(Value::String("param1".to_string()), Value::Bool(true));
|
||||
let vars = vec![Variable {
|
||||
name: "var1".to_string(),
|
||||
var_type: "test".to_string(),
|
||||
params,
|
||||
}];
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
vars:
|
||||
- name: var1
|
||||
type: test
|
||||
params:
|
||||
param1: true
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
vars,
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vars_no_params_maps_correctly() {
|
||||
let vars = vec![Variable {
|
||||
name: "var1".to_string(),
|
||||
var_type: "test".to_string(),
|
||||
params: Mapping::new(),
|
||||
}];
|
||||
assert_eq!(
|
||||
create_match(
|
||||
r#"
|
||||
trigger: "Hello"
|
||||
replace: "world"
|
||||
vars:
|
||||
- name: var1
|
||||
type: test
|
||||
"#
|
||||
)
|
||||
.unwrap(),
|
||||
Match {
|
||||
cause: MatchCause::Trigger(TriggerCause {
|
||||
triggers: vec!["Hello".to_string()],
|
||||
..Default::default()
|
||||
}),
|
||||
effect: MatchEffect::Text(TextEffect {
|
||||
replace: "world".to_string(),
|
||||
vars,
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -91,7 +91,10 @@ mod tests {
|
|||
server.accept_one().unwrap();
|
||||
});
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
|
||||
let client = client::<Event>("testespansoipc", &std::env::temp_dir()).unwrap();
|
||||
client.send(Event::Foo("hello".to_string())).unwrap();
|
||||
|
||||
|
|
|
@ -17,5 +17,6 @@ wayland = ["espanso-detect/wayland", "espanso-inject/wayland"]
|
|||
espanso-detect = { path = "../espanso-detect" }
|
||||
espanso-ui = { path = "../espanso-ui" }
|
||||
espanso-inject = { path = "../espanso-inject" }
|
||||
espanso-config = { path = "../espanso-config" }
|
||||
maplit = "1.0.2"
|
||||
simplelog = "0.9.0"
|
Loading…
Reference in New Issue
Block a user