BastliBridge

git clone git://xatko.vsos.ethz.ch/BastliBridge.git
Log | Files | Refs | Submodules | README

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;