add support for "general" config in the module loader. The "general" config is found under the "general" heading and is passed to each module constructor.

This commit is contained in:
Adrian Malacoda 2017-02-26 02:44:53 -06:00
parent 0a45cbb9f2
commit fd1aecf4d3
8 changed files with 25 additions and 20 deletions

View File

@ -22,7 +22,7 @@ pub struct DiscordModule {
const DEFAULT_PLAYING: &'static str = "tenquestionmarks 0.0.1"; const DEFAULT_PLAYING: &'static str = "tenquestionmarks 0.0.1";
impl DiscordModule { impl DiscordModule {
pub fn new (configuration: &Table) -> Box<Module> { pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
let token = configuration.get("token") let token = configuration.get("token")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or(""); .unwrap_or("");

View File

@ -13,7 +13,7 @@ pub struct EchoModule {
} }
impl EchoModule { impl EchoModule {
pub fn new (configuration: &Table) -> Box<Module> { pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
let prefix = configuration.get("prefix") let prefix = configuration.get("prefix")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or("!echo"); .unwrap_or("!echo");

View File

@ -15,7 +15,7 @@ pub struct EchoboxModule {
} }
impl EchoboxModule { impl EchoboxModule {
pub fn new (configuration: &Table) -> Box<Module> { pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
let prefix = configuration.get("prefix") let prefix = configuration.get("prefix")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or("?echobox"); .unwrap_or("?echobox");

View File

@ -14,31 +14,36 @@ use modules::pvn::PvnModule;
use modules::echobox::EchoboxModule; use modules::echobox::EchoboxModule;
pub struct ModuleLoader { pub struct ModuleLoader {
types: BTreeMap<&'static str, fn(&Table) -> Box<Module>> types: BTreeMap<&'static str, fn(&Table, &Table) -> Box<Module>>
} }
impl ModuleLoader { impl ModuleLoader {
pub fn new () -> ModuleLoader { pub fn new () -> ModuleLoader {
let mut types = BTreeMap::new(); let mut types = BTreeMap::new();
types.insert("discord", DiscordModule::new as fn(&Table) -> Box<Module>); types.insert("discord", DiscordModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("lua", LuaModule::new as fn(&Table) -> Box<Module>); types.insert("lua", LuaModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("stdin", StdinModule::new as fn(&Table) -> Box<Module>); types.insert("stdin", StdinModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("echo", EchoModule::new as fn(&Table) -> Box<Module>); types.insert("echo", EchoModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("random", RandomModule::new as fn(&Table) -> Box<Module>); types.insert("random", RandomModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("pvn", PvnModule::new as fn(&Table) -> Box<Module>); types.insert("pvn", PvnModule::new as fn(&Table, &Table) -> Box<Module>);
types.insert("echobox", EchoboxModule::new as fn(&Table) -> Box<Module>); types.insert("echobox", EchoboxModule::new as fn(&Table, &Table) -> Box<Module>);
ModuleLoader { ModuleLoader {
types: types types: types
} }
} }
pub fn load_from_configuration (&self, configuration: Table) -> Result<BTreeMap<String, Box<Module>>, ModuleLoaderError> { pub fn load_from_configuration (&self, configuration: Table) -> Result<BTreeMap<String, Box<Module>>, ModuleLoaderError> {
let general_config = configuration.get("general")
.and_then(|value| value.as_table())
.map(|value| value.clone())
.unwrap_or_else(|| BTreeMap::new());
configuration.into_iter().filter(|&(ref key, _)| { configuration.into_iter().filter(|&(ref key, _)| {
key != "general" key != "general"
}).map(|(key, value)| { }).map(|(key, value)| {
match value.as_table() { match value.as_table() {
Some(table) => { Some(table) => {
let module = self.load_single_module(&key, table)?; let module = self.load_single_module(&key, &general_config, table)?;
Result::Ok((key, module)) Result::Ok((key, module))
}, },
None => Result::Err(ModuleLoaderError { message: format!("Bad configuration parameters for module instance: {}. Configuration for a Module must be a table.", key) }) None => Result::Err(ModuleLoaderError { message: format!("Bad configuration parameters for module instance: {}. Configuration for a Module must be a table.", key) })
@ -46,17 +51,17 @@ impl ModuleLoader {
}).collect() }).collect()
} }
pub fn load_single_module (&self, name: &str, configuration: &Table) -> Result<Box<Module>, ModuleLoaderError> { pub fn load_single_module (&self, name: &str, general_configuration: &Table, module_configuration: &Table) -> Result<Box<Module>, ModuleLoaderError> {
/* /*
* The Module type defaults to the instance name (in the tenquestionmarks configuration) * The Module type defaults to the instance name (in the tenquestionmarks configuration)
* but can explicitly be set by using the special "type" parameter. * but can explicitly be set by using the special "type" parameter.
*/ */
let module_type: &str = configuration.get("type") let module_type: &str = module_configuration.get("type")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or(name); .unwrap_or(name);
match self.types.get(module_type) { match self.types.get(module_type) {
Some(constructor) => Result::Ok(constructor(configuration)), Some(constructor) => Result::Ok(constructor(general_configuration, module_configuration)),
None => Result::Err(ModuleLoaderError { message: format!("No such module type: {}", module_type) }) None => Result::Err(ModuleLoaderError { message: format!("No such module type: {}", module_type) })
} }
} }

View File

@ -22,7 +22,7 @@ pub struct LuaModule {
} }
impl LuaModule { impl LuaModule {
pub fn new (config: &Table) -> Box<Module> { pub fn new (_: &Table, config: &Table) -> Box<Module> {
Box::new(LuaModule { Box::new(LuaModule {
code: config.get("code").and_then(|value| value.as_str()).map(String::from), code: config.get("code").and_then(|value| value.as_str()).map(String::from),
file: config.get("file").and_then(|value| value.as_str()).map(String::from), file: config.get("file").and_then(|value| value.as_str()).map(String::from),

View File

@ -17,7 +17,7 @@ use pvn::ninjas::{Ninja, Ninjas};
pub struct PvnModule {} pub struct PvnModule {}
impl PvnModule { impl PvnModule {
pub fn new (_: &Table) -> Box<Module> { pub fn new (_: &Table, _: &Table) -> Box<Module> {
Box::new(PvnModule {}) Box::new(PvnModule {})
} }
} }

View File

@ -15,10 +15,10 @@ pub struct RandomModule {
} }
impl RandomModule { impl RandomModule {
pub fn new (configuration: &Table) -> Box<Module> { pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
let prefix = configuration.get("prefix") let prefix = configuration.get("prefix")
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or("!random "); .unwrap_or("?random");
let responses = configuration.get("responses") let responses = configuration.get("responses")
.and_then(|value| value.as_slice()) .and_then(|value| value.as_slice())

View File

@ -25,7 +25,7 @@ impl MessageSender for StdinMessageSender {
} }
impl StdinModule { impl StdinModule {
pub fn new (_: &Table) -> Box<Module> { pub fn new (_: &Table, _: &Table) -> Box<Module> {
Box::new(StdinModule {}) Box::new(StdinModule {})
} }
} }