From a01ad46efa8cbffd049ac3c700732dce01be5860 Mon Sep 17 00:00:00 2001 From: Adrian Malacoda Date: Sat, 24 Feb 2018 18:54:44 -0600 Subject: [PATCH] make it (theoretically) possible to reconfigure a module. Might have some sort of file watcher thread which periodically checks to see if config file has been modified and reconfigures if necessary. --- src/lib.rs | 8 +++++++ src/modules/mod.rs | 6 ++++++ src/modules/random.rs | 49 +++++++++++++++++++++++++------------------ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ce7775f..ea96575 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,14 @@ impl Tenquestionmarks { Result::Ok(Tenquestionmarks::with_modules(modules)) } + pub fn reconfigure (&mut self, configuration: &Table) { + for (key, module_configuration) in configuration { + if let (Some(module_configuration_table), Some(ref mut module)) = (module_configuration.as_table(), self.modules.get_mut(key)) { + module.reconfigure(module_configuration_table.clone()); + } + } + } + pub fn run (&self) { crossbeam::scope(|scope| { let mut dispatchers: BTreeMap<&str, Receiver> = BTreeMap::new(); diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 720e458..ddb2e88 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -29,6 +29,11 @@ impl Module { self.event_loop.run(sender, receiver); } + pub fn reconfigure (&mut self, configuration: Table) { + self.event_loop.reconfigure(&configuration); + self.config = configuration; + } + pub fn parents (&self) -> Vec { self.config.get("parents") .and_then(|value| value.as_array()) @@ -56,4 +61,5 @@ impl Module { pub trait EventLoop : Sync { fn run (&self, _: Box>, _: Receiver>) {} + fn reconfigure (&mut self, _: &Table) {} } diff --git a/src/modules/random.rs b/src/modules/random.rs index 0fd6ceb..fe71bb1 100644 --- a/src/modules/random.rs +++ b/src/modules/random.rs @@ -18,32 +18,41 @@ pub struct RandomModule { impl RandomModule { pub fn new (_: &Table, configuration: &Table) -> Box { - let pattern = configuration.get("pattern") - .and_then(|value| value.as_str()) - .map(String::from) - .or_else(|| configuration.get("prefix") - .and_then(|value| value.as_str()) - .map(|value| format!("^{}", regex::escape(value)))) - .and_then(|value| Regex::new(&value).ok()) - .expect("Invalid value for pattern"); - - let responses = configuration.get("responses") - .and_then(|value| value.as_array()) - .map(|value| value.to_vec()) - .unwrap_or(vec![]) - .into_iter() - .map(|value| { String::from(value.as_str().unwrap()) }) - .collect(); - Box::new(RandomModule { - pattern: pattern, - responses: responses + pattern: RandomModule::pattern_from_config(&configuration), + responses: RandomModule::responses_from_config(&configuration) }) } + + fn pattern_from_config (configuration: &Table) -> Regex { + configuration.get("pattern") + .and_then(|value| value.as_str()) + .map(String::from) + .or_else(|| configuration.get("prefix") + .and_then(|value| value.as_str()) + .map(|value| format!("^{}", regex::escape(value)))) + .and_then(|value| Regex::new(&value).ok()) + .expect("Invalid value for pattern") + } + + fn responses_from_config (configuration: &Table) -> Vec { + configuration.get("responses") + .and_then(|value| value.as_array()) + .map(|value| value.to_vec()) + .unwrap_or(vec![]) + .into_iter() + .map(|value| { String::from(value.as_str().unwrap()) }) + .collect() + } } impl EventLoop for RandomModule { - fn run(&self, _: Box>, receiver: Receiver>) { + fn reconfigure (&mut self, configuration: &Table) { + self.pattern = RandomModule::pattern_from_config(&configuration); + self.responses = RandomModule::responses_from_config(&configuration) + } + + fn run (&self, _: Box>, receiver: Receiver>) { let mut rng = rand::thread_rng(); loop {