begin tenquestionmarks 0.0.2. Separate Module trait into Module struct (which holds metadata and config about the module) and EventLoop trait, which implements the event loop. The constructors still return Modules, but they are structs and not boxes.
This commit is contained in:
parent
23e32f28fe
commit
9e9da11f79
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name="tenquestionmarks"
|
||||
version="0.0.1"
|
||||
version="0.0.2"
|
||||
authors=["Adrian Malacoda <adrian.malacoda@monarch-pass.net>"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -15,15 +15,45 @@ pub enum Event {
|
||||
pub struct Envelope {
|
||||
pub from: Option<String>,
|
||||
pub event: Event,
|
||||
pub to: Vec<String>
|
||||
pub to: Vec<String>,
|
||||
pub tags: Vec<String>
|
||||
}
|
||||
|
||||
impl Envelope {
|
||||
pub fn new (event: Event) -> Envelope {
|
||||
let mut tags: Vec<String> = vec![];
|
||||
|
||||
match &event {
|
||||
&Event::Message { ref message } => {
|
||||
tags.push(format!("user:{:}", message.author.name));
|
||||
match message.channel {
|
||||
Some(ref channel) => {
|
||||
tags.push(format!("channel:{:}", channel.name));
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
},
|
||||
&Event::SelfJoin { ref channel } => {
|
||||
tags.push(format!("channel:{:}", channel.name));
|
||||
},
|
||||
&Event::SelfQuit { ref channel } => {
|
||||
tags.push(format!("channel:{:}", channel.name));
|
||||
},
|
||||
&Event::UserJoin { ref channel, ref user } => {
|
||||
tags.push(format!("channel:{:}", channel.name));
|
||||
tags.push(format!("user:{:}", user.name));
|
||||
},
|
||||
&Event::UserQuit { ref channel, ref user } => {
|
||||
tags.push(format!("channel:{:}", channel.name));
|
||||
tags.push(format!("user:{:}", user.name));
|
||||
}
|
||||
}
|
||||
|
||||
Envelope {
|
||||
from: None,
|
||||
event: event,
|
||||
to: vec![]
|
||||
to: vec![],
|
||||
tags: tags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,8 @@ impl Tenquestionmarks {
|
||||
Envelope {
|
||||
from: Some(from.clone()),
|
||||
event: envelope.event,
|
||||
to: envelope.to
|
||||
to: envelope.to,
|
||||
tags: envelope.tags
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -19,8 +19,12 @@ use regex::Regex;
|
||||
pub struct AutolinkModule {}
|
||||
|
||||
impl AutolinkModule {
|
||||
pub fn new (_: &Table, _: &Table) -> Box<Module> {
|
||||
Box::new(AutolinkModule {})
|
||||
pub fn new (_: &Table, config: &Table) -> Module {
|
||||
Module {
|
||||
event_loop: Box::new(AutolinkModule {}),
|
||||
module_type: String::from("autolink"),
|
||||
config: config.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +98,7 @@ fn print_any_link (link: &Link, message: &Message) {
|
||||
message.reply(&format!("**Autolink:** {} -> {}", link.label(), link.url()));
|
||||
}
|
||||
|
||||
impl Module for AutolinkModule {
|
||||
impl EventLoop for AutolinkModule {
|
||||
fn run (&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let link_regex = Regex::new(r"\[\[([^\[\]]*)\]\]").expect("Invalid regex...");
|
||||
let mut searchers = AggregateSearcher::new();
|
||||
|
@ -3,6 +3,7 @@ use discord::Discord;
|
||||
use discord::model::{Event, PossibleServer};
|
||||
|
||||
use modules::Module;
|
||||
use modules::EventLoop;
|
||||
use toml::Table;
|
||||
|
||||
use event;
|
||||
@ -19,10 +20,10 @@ pub struct DiscordModule {
|
||||
playing: String
|
||||
}
|
||||
|
||||
const DEFAULT_PLAYING: &'static str = "tenquestionmarks 0.0.1";
|
||||
const DEFAULT_PLAYING: &'static str = "tenquestionmarks 0.0.2";
|
||||
|
||||
impl DiscordModule {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Module {
|
||||
let token = configuration.get("token")
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("");
|
||||
@ -31,10 +32,14 @@ impl DiscordModule {
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or(DEFAULT_PLAYING);
|
||||
|
||||
Box::new(DiscordModule {
|
||||
Module {
|
||||
module_type: String::from("Discord"),
|
||||
event_loop: Box::new(DiscordModule {
|
||||
token: String::from(token),
|
||||
playing: String::from(playing)
|
||||
})
|
||||
}),
|
||||
config: configuration.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +58,7 @@ impl MessageSender for DiscordMessageSender {
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for DiscordModule {
|
||||
impl EventLoop for DiscordModule {
|
||||
fn run (&self, sender: Box<ExtSender<event::Envelope>>, _: Receiver<Arc<event::Envelope>>) {
|
||||
let discord = Arc::new(Discord::from_bot_token(&self.token[..]).expect("Discord module: Login failed"));
|
||||
let (mut connection, _) = discord.connect().expect("Discord module: Connection failed");
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -13,18 +13,22 @@ pub struct EchoModule {
|
||||
}
|
||||
|
||||
impl EchoModule {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Module {
|
||||
let prefix = configuration.get("prefix")
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("!echo");
|
||||
|
||||
Box::new(EchoModule {
|
||||
Module {
|
||||
module_type: String::from("echo"),
|
||||
event_loop: Box::new(EchoModule {
|
||||
prefix: String::from(prefix)
|
||||
})
|
||||
}),
|
||||
config: configuration.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for EchoModule {
|
||||
impl EventLoop for EchoModule {
|
||||
fn run(&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
loop {
|
||||
match receiver.recv() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -15,7 +15,7 @@ pub struct EchoboxModule {
|
||||
}
|
||||
|
||||
impl EchoboxModule {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Module {
|
||||
let prefix = configuration.get("prefix")
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("?echobox");
|
||||
@ -24,14 +24,18 @@ impl EchoboxModule {
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("echobox.db");
|
||||
|
||||
Box::new(EchoboxModule {
|
||||
Module {
|
||||
module_type: String::from("echo"),
|
||||
event_loop: Box::new(EchoboxModule {
|
||||
prefix: String::from(prefix),
|
||||
file: String::from(file)
|
||||
})
|
||||
}),
|
||||
config: configuration.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for EchoboxModule {
|
||||
impl EventLoop for EchoboxModule {
|
||||
fn run(&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let echobox = Echobox::with_file(&self.file).unwrap();
|
||||
|
||||
|
@ -15,26 +15,26 @@ use modules::echobox::EchoboxModule;
|
||||
use modules::autolink::AutolinkModule;
|
||||
|
||||
pub struct ModuleLoader {
|
||||
types: BTreeMap<&'static str, fn(&Table, &Table) -> Box<Module>>
|
||||
types: BTreeMap<&'static str, fn(&Table, &Table) -> Module>
|
||||
}
|
||||
|
||||
impl ModuleLoader {
|
||||
pub fn new () -> ModuleLoader {
|
||||
let mut types = BTreeMap::new();
|
||||
types.insert("discord", DiscordModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("lua", LuaModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("stdin", StdinModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("echo", EchoModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("random", RandomModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("pvn", PvnModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("echobox", EchoboxModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("autolink", AutolinkModule::new as fn(&Table, &Table) -> Box<Module>);
|
||||
types.insert("discord", DiscordModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("lua", LuaModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("stdin", StdinModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("echo", EchoModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("random", RandomModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("pvn", PvnModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("echobox", EchoboxModule::new as fn(&Table, &Table) -> Module);
|
||||
types.insert("autolink", AutolinkModule::new as fn(&Table, &Table) -> Module);
|
||||
ModuleLoader {
|
||||
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, Module>, ModuleLoaderError> {
|
||||
let general_config = configuration.get("general")
|
||||
.and_then(|value| value.as_table())
|
||||
.map(|value| value.clone())
|
||||
@ -53,7 +53,7 @@ impl ModuleLoader {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn load_single_module (&self, name: &str, general_configuration: &Table, module_configuration: &Table) -> Result<Box<Module>, ModuleLoaderError> {
|
||||
pub fn load_single_module (&self, name: &str, general_configuration: &Table, module_configuration: &Table) -> Result<Module, ModuleLoaderError> {
|
||||
/*
|
||||
* The Module type defaults to the instance name (in the tenquestionmarks configuration)
|
||||
* but can explicitly be set by using the special "type" parameter.
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
|
||||
use toml::{Table, Value};
|
||||
|
||||
@ -22,12 +22,16 @@ pub struct LuaModule {
|
||||
}
|
||||
|
||||
impl LuaModule {
|
||||
pub fn new (_: &Table, config: &Table) -> Box<Module> {
|
||||
Box::new(LuaModule {
|
||||
pub fn new (_: &Table, config: &Table) -> Module {
|
||||
Module {
|
||||
module_type: String::from("lua"),
|
||||
event_loop: Box::new(LuaModule {
|
||||
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),
|
||||
variables: config.clone()
|
||||
})
|
||||
}),
|
||||
config: config.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +52,7 @@ implement_lua_push!(Message, |mut metatable| {
|
||||
index.set("reply", hlua::function2(|message: &mut Message, reply: String| message.reply(&reply)));
|
||||
});
|
||||
|
||||
impl Module for LuaModule {
|
||||
impl EventLoop for LuaModule {
|
||||
fn run (&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let mut lua = Lua::new();
|
||||
lua.openlibs();
|
||||
|
@ -16,7 +16,15 @@ use std::sync::Arc;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use transformable_channels::mpsc::ExtSender;
|
||||
|
||||
pub trait Module : Sync {
|
||||
fn register (&self, _: &Tenquestionmarks) {}
|
||||
use toml::Table;
|
||||
|
||||
pub struct Module {
|
||||
event_loop: Box<EventLoop>,
|
||||
module_type: String,
|
||||
config: Table
|
||||
}
|
||||
|
||||
impl Module {}
|
||||
pub trait EventLoop : Sync {
|
||||
fn run (&self, _: Box<ExtSender<Envelope>>, _: Receiver<Arc<Envelope>>) {}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -17,8 +17,12 @@ use pvn::ninjas::{Ninja, Ninjas};
|
||||
pub struct PvnModule {}
|
||||
|
||||
impl PvnModule {
|
||||
pub fn new (_: &Table, _: &Table) -> Box<Module> {
|
||||
Box::new(PvnModule {})
|
||||
pub fn new (_: &Table, configuration: &Table) -> Module {
|
||||
Module {
|
||||
module_type: String::from("pvn"),
|
||||
event_loop: Box::new(PvnModule {}),
|
||||
config: configuration.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +140,7 @@ impl PirateVsNinja {
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for PvnModule {
|
||||
impl EventLoop for PvnModule {
|
||||
fn run(&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let mut pvn = PirateVsNinja {
|
||||
pirates: Pirates::new(),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use std::sync::Arc;
|
||||
@ -15,7 +15,7 @@ pub struct RandomModule {
|
||||
}
|
||||
|
||||
impl RandomModule {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Box<Module> {
|
||||
pub fn new (_: &Table, configuration: &Table) -> Module {
|
||||
let prefix = configuration.get("prefix")
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or("?random");
|
||||
@ -28,14 +28,18 @@ impl RandomModule {
|
||||
.map(|value| { String::from(value.as_str().unwrap()) })
|
||||
.collect();
|
||||
|
||||
Box::new(RandomModule {
|
||||
Module {
|
||||
module_type: String::from("random"),
|
||||
event_loop: Box::new(RandomModule {
|
||||
prefix: String::from(prefix),
|
||||
responses: responses
|
||||
})
|
||||
}),
|
||||
config: configuration.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for RandomModule {
|
||||
impl EventLoop for RandomModule {
|
||||
fn run(&self, _: Box<ExtSender<Envelope>>, receiver: Receiver<Arc<Envelope>>) {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::io;
|
||||
|
||||
use modules::Module;
|
||||
use modules::{Module, EventLoop};
|
||||
use toml::Table;
|
||||
|
||||
use {MessageSender, Message, User};
|
||||
@ -25,12 +25,16 @@ impl MessageSender for StdinMessageSender {
|
||||
}
|
||||
|
||||
impl StdinModule {
|
||||
pub fn new (_: &Table, _: &Table) -> Box<Module> {
|
||||
Box::new(StdinModule {})
|
||||
pub fn new (_: &Table, config: &Table) -> Module {
|
||||
Module {
|
||||
module_type: String::from("stdin"),
|
||||
event_loop: Box::new(StdinModule {}),
|
||||
config: config.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for StdinModule {
|
||||
impl EventLoop for StdinModule {
|
||||
fn run(&self, sender: Box<ExtSender<Envelope>>, _: Receiver<Arc<Envelope>>) {
|
||||
loop {
|
||||
let mut input = String::new();
|
||||
|
Loading…
x
Reference in New Issue
Block a user