Add Random Extension to enable non-deterministic matches

This commit is contained in:
Federico Terzi 2019-12-13 22:52:24 +01:00
parent 5db9d92642
commit 4c172a9d54
4 changed files with 100 additions and 3 deletions

7
Cargo.lock generated
View File

@ -384,6 +384,7 @@ dependencies = [
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1003,7 +1004,7 @@ dependencies = [
[[package]]
name = "rand"
version = "0.7.0"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1410,7 +1411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1892,7 +1893,7 @@ dependencies = [
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"

View File

@ -29,6 +29,7 @@ reqwest = "0.9.20"
git2 = {version = "0.10.1", features = ["https"]}
tempfile = "3.1.0"
dialoguer = "0.4.0"
rand = "0.7.2"
[target.'cfg(unix)'.dependencies]
libc = "0.2.62"

View File

@ -22,6 +22,7 @@ use serde_yaml::Mapping;
mod date;
mod shell;
mod script;
mod random;
pub trait Extension {
fn name(&self) -> String;
@ -33,5 +34,6 @@ pub fn get_extensions() -> Vec<Box<dyn Extension>> {
Box::new(date::DateExtension::new()),
Box::new(shell::ShellExtension::new()),
Box::new(script::ScriptExtension::new()),
Box::new(random::RandomExtension::new()),
]
}

93
src/extension/random.rs Normal file
View File

@ -0,0 +1,93 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019 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 serde_yaml::{Mapping, Value};
use rand::seq::SliceRandom;
use log::{warn, error};
pub struct RandomExtension {}
impl RandomExtension {
pub fn new() -> RandomExtension {
RandomExtension{}
}
}
impl super::Extension for RandomExtension {
fn name(&self) -> String {
String::from("random")
}
fn calculate(&self, params: &Mapping) -> Option<String> {
let choices = params.get(&Value::from("choices"));
if choices.is_none() {
warn!("No 'choices' parameter specified for random variable");
return None
}
let choices = choices.unwrap().as_sequence();
if let Some(choices) = choices {
let str_choices = choices.iter().map(|arg| {
arg.as_str().unwrap_or_default().to_string()
}).collect::<Vec<String>>();
// Select a random choice between the possibilities
let choice = str_choices.choose(&mut rand::thread_rng());
match choice {
Some(output) => {
return Some(output.clone())
},
None => {
error!("Could not select a random choice.");
return None
},
}
}
error!("choices array have an invalid format '{:?}'", choices);
None
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::extension::Extension;
#[test]
fn test_random_basic() {
let mut params = Mapping::new();
let choices = vec!(
"first",
"second",
"third",
);
params.insert(Value::from("choices"), Value::from(choices.clone()));
let extension = RandomExtension::new();
let output = extension.calculate(&params);
assert!(output.is_some());
let output = output.unwrap();
assert!(choices.iter().any(|x| x == &output));
}
}