command.d (1929B)
1 module bastlibridge.command; 2 import bastlibridge.base; 3 import bastlibridge.manager; 4 import std.datetime : SysTime; 5 import std.exception; 6 import std.format; 7 import std.meta; 8 import std.conv; 9 import std.algorithm; 10 import std.traits; 11 import std.experimental.logger; 12 13 class CommandException : Exception{ 14 this(string msg, string file= __FILE__, size_t line=__LINE__, Throwable next=null){ 15 super(msg,file,line,next); 16 } 17 } 18 19 struct CommandOptions{ 20 bool admin=false; 21 } 22 23 struct CommandMachine{ 24 struct Function{ 25 void function(Message m, in char[] args) func; 26 CommandOptions co; 27 } 28 Function[string] commands; 29 30 bool available(in char[] name){ 31 return cast(bool)(name in commands); 32 } 33 34 void execute(in char[] name, Message m, in char[] args, bool handleErrors=true) 35 in{ 36 assert(name); 37 assert(m); 38 } 39 do{ 40 try{ 41 auto cmd=enforce!CommandException(name in commands, format("Command %s unknown", name)); 42 if(cmd.co.admin && !m.auth()){ 43 throw new CommandException("Permission denied"); 44 } 45 cmd.func(m, args); 46 } 47 catch(Exception e){ 48 if(handleErrors){ 49 m.respond(e.msg); 50 warning(e.toString); 51 } 52 else{ 53 throw e; 54 } 55 } 56 } 57 58 static void wrapperFunction(alias T)(Message m, in char[] args) if(isCallable!T){ 59 auto s=args.splitter(" "); 60 auto pop(){ 61 if(s.empty) 62 throw new Exception("Too few arguments given"); 63 auto ret=s.front; 64 s.popFront(); 65 return ret; 66 } 67 alias fct=staticMap!(to,Parameters!T[1..$]); 68 69 auto ref evaluate(alias Func)(){ 70 return Func(pop()); 71 } 72 73 T(m, staticMap!(evaluate, fct)); 74 } 75 76 void add(alias T)(string name){ 77 static if(hasUDA!(T, CommandOptions)){ 78 add!T(name, getUDA!(T, CommandOptions)); 79 } 80 else{ 81 add!T(name, CommandOptions.init); 82 } 83 84 } 85 void add(alias T)(string name, CommandOptions co) if(isCallable!T && is(Parameters!T[0] == Message)){ 86 commands[name]=Function(&wrapperFunction!T, co); 87 } 88 } 89 CommandMachine globalCommands;