#pragmaonce #include<functional> #include"http.h" #include"json_wrapper.h" #include"error.h" namespace SleepyDiscord { structStandardResponse:Response{//This is here for possiable future use explicitStandardResponse(const Response& response):Response(response){} }; structBooleanResponse:publicStandardResponse{ public: using StandardResponse::StandardResponse; using Callback = std::function<bool(const Response& response)>; using Type =bool; BooleanResponse(const Response& response,const Callback callback): StandardResponse(response),wasSuccessful(callback){} inlineoperatorType()const{ returnwasSuccessful(*this)||!error(); } Type operator*()const{ returnoperatorType(); } inline Type cast(){ returnoperatorType(); } //this isn't a function so that we can override it during construction. //this isn't a virtual function because then we need lots of child classes //this isn't used in a template because then the user would have to write the right error handling function const Callback wasSuccessful =[](const Response&/*response*/){returntrue;}; }; typedef BooleanResponse BoolResponse; template<ErrorCode Code> inlineconst BooleanResponse::Callback SuccessCodeFn(){ return[](const Response& response){return response.statusCode == Code;}; } inlineconst BooleanResponse::Callback EmptyRespFn(){ return SuccessCodeFn<NO_CONTENT>(); } inlineconst BooleanResponse::Callback StandardRespFn(){ return SuccessCodeFn<OK>(); } template<class_Type> structObjectResponse:publicStandardResponse{ using StandardResponse::StandardResponse; using Type = _Type; operatorType(){//to do use references instead of pointers returnerror()?Type():Type(text); } Type&operator*()const{ returnoperatorType(); } inline Type cast(){ returnoperatorType(); } inlineboolcast(Type& value){ if(error()) returnfalse; rapidjson::Document doc; rapidjson::ParseResult isOK = doc.Parse(text.c_str(), text.length()); if(!isOK) returnfalse; value =Type(doc); returntrue; } }; structArrayResponseWrapper:publicStandardResponse{ using StandardResponse::StandardResponse; using Type = std::string; inlineoperatorconst std::string&()const{ return text; } inline rapidjson::Document getDoc(){ rapidjson::Document arr;//ARR, I'm a pirate arr.Parse(text.data(), text.length()); return arr; } template<classCallback> inline rapidjson::ParseResult getDoc(Callback& callback){ rapidjson::Document arr; rapidjson::ParseResult isOK = arr.Parse(text.data(), text.length()); if(isOK)callback(arr); return isOK; } }; template<classType> using ArrayResponse = json::ArrayWrapper<Type, ArrayResponseWrapper>; structStringResponse:publicStandardResponse{ using StandardResponse::StandardResponse; using Type = std::string; inlineoperatorconst Type&()const{ return text; } }; using VoidResponse = StringResponse; }