2019-10-29 22:24:41 +01:00
use serenity ::model ::channel ::Message ;
2019-10-30 22:04:32 +01:00
use std ::fmt ;
use serenity ::model ::id ::ChannelId ;
use serde ::de ::DeserializeOwned ;
2019-10-29 22:24:41 +01:00
use serenity ::prelude ::* ;
2019-10-30 23:00:51 +01:00
mod apt ;
2019-10-29 22:24:41 +01:00
mod pacman ;
2019-10-31 10:39:28 +01:00
mod nix ;
2019-10-30 22:04:32 +01:00
extern crate reqwest ;
2019-10-29 22:24:41 +01:00
pub struct Handler ;
2019-10-30 23:00:51 +01:00
pub type CommandHandler = dyn Fn ( Context , Message , Vec < & str > ) ;
2019-10-29 22:24:41 +01:00
struct Command {
trigger : String ,
handler : Box < CommandHandler > ,
}
unsafe impl Sync for Command { }
const PREFIX : char = '!' ;
impl EventHandler for Handler {
fn message ( & self , ctx : Context , msg : Message ) {
if msg . content . starts_with ( PREFIX ) {
if let Some ( command ) = COMMANDS
. iter ( )
. filter ( | & c | msg . content . starts_with ( & c . trigger ) )
. next ( )
{
2019-10-30 23:00:51 +01:00
let content = msg . content . clone ( ) ;
let mut args = content . split_whitespace ( ) . collect ::< Vec < _ > > ( ) ;
// the prefix + trigger
args . remove ( 0 ) ;
if args . len ( ) = = 0 {
send (
msg . channel_id ,
" Error: expected at least 1 additional argument " ,
& ctx ,
) ;
return ;
}
( * command . handler ) ( ctx , msg , args ) ;
2019-10-29 22:24:41 +01:00
} ;
}
}
}
lazy_static! {
static ref COMMANDS : Vec < Command > = {
let mut command_list = Vec ::new ( ) ;
command_list . push ( Command ::new ( " pacman " , pacman ::query_pacman ) ) ;
2019-10-30 23:00:51 +01:00
command_list . push ( Command ::new ( " apt " , apt ::query_apt ) ) ;
2019-10-31 10:39:28 +01:00
command_list . push ( Command ::new ( " nix " , nix ::query_nix ) ) ;
2019-10-29 22:24:41 +01:00
command_list
} ;
}
impl Command {
2019-10-30 23:00:51 +01:00
pub fn new ( trigger : & str , handler : fn ( Context , Message , Vec < & str > ) ) -> Self {
2019-10-29 22:24:41 +01:00
let mut trigger_with_prefix = trigger . to_string ( ) ;
trigger_with_prefix . insert ( 0 , PREFIX ) ;
Self {
trigger : trigger_with_prefix ,
handler : Box ::new ( handler ) ,
}
}
}
2019-10-30 22:04:32 +01:00
pub fn send ( target : ChannelId , message : & str , ctx : & Context ) {
if let Err ( cause ) = target . say ( & ctx . http , message ) {
println! ( " Could not send message: {} " , cause ) ;
}
}
pub fn respond_with_results < T : fmt ::Display > ( target : ChannelId , results : & Vec < T > , ctx : & Context ) {
send (
target ,
& format! (
" ```{}``` " ,
results
. into_iter ( )
. take ( 5 )
. map ( | p | format! ( " {} \n " , p ) )
. collect ::< String > ( )
) ,
ctx ,
) ;
}
2019-10-31 10:39:28 +01:00
pub fn search < T : DeserializeOwned > ( url : & str , fallback : impl Fn ( reqwest ::Error ) -> T ) -> T {
return search_inner ( url ) . unwrap_or_else ( fallback ) ;
2019-10-30 22:04:32 +01:00
}
fn search_inner < T : DeserializeOwned > ( url : & str ) -> Result < T , reqwest ::Error > {
let resp = reqwest ::get ( url ) ? . json ::< T > ( ) ? ;
Ok ( resp )
}