diff --git a/src/common/APIRequest.hpp b/src/common/APIRequest.hpp new file mode 100644 index 000000000..cb118c457 --- /dev/null +++ b/src/common/APIRequest.hpp @@ -0,0 +1,115 @@ +#pragma once +#include + +#include "common/NetworkCommon.hpp" +#include "common/NetworkRequest.hpp" +#include "common/NetworkResult.hpp" +#include "common/Outcome.hpp" + +namespace chatterino { + +// i can't make it not pass something, so this is a small type that does nothing +struct APIRequestNoErrorValue { +}; +template +class APIRequestData +{ + using APISuceessCallback = std::function; + using APIErrorCallback = std::function; + using APIFinallyCallback = std::function; + +public: + APISuceessCallback onSuccess; + APIErrorCallback onError; + APIFinallyCallback finally; +}; + +template +class APIRequest +{ + using APISuceessCallback = std::function; + using APIErrorCallback = std::function; + using APIFinallyCallback = std::function; + +private: + NetworkRequest underlying_; + std::shared_ptr> data_; + +public: + // move = good + APIRequest(APIRequest &&other) = default; + APIRequest &operator=(APIRequest &&other) = default; + + // copy = bad + APIRequest(const APIRequest &other) = delete; + APIRequest &operator=(const APIRequest &other) = delete; + + explicit APIRequest( + QUrl url, NetworkRequestType requestType, + std::function successTransformer, + std::function errorTransformer = nullptr, + std::function onFinally = nullptr) + : underlying_(std::move(url), requestType) + , data_(std::make_shared>()) + { + auto data = this->data_; + this->underlying_ = + std::move(this->underlying_) + .timeout(5 * 1000) + .onSuccess( + [data, successTransformer](NetworkResult res) -> Outcome { + OkType val = successTransformer(res); + return data->onSuccess(res, val); + }) + .onError([data, errorTransformer](NetworkResult res) { + if (errorTransformer) + { + ErrorType err = errorTransformer(res); + data->onError(res, err); + } + }) + .finally([data, onFinally]() { + if (onFinally) + { + onFinally(); + } + if (data->finally) + { + data->finally(); + } + }); + }; + + APIRequest header(const char *headerName, + const char *value) && + { + this->underlying_ = + std::move(this->underlying_).header(headerName, value); + return std::move(*this); + } + + APIRequest onError(APIErrorCallback cb) && + { + this->data_->onError = cb; + return std::move(*this); + }; + + APIRequest onSuccess(APISuceessCallback cb) && + { + this->data_->onSuccess = cb; + return std::move(*this); + }; + + APIRequest finally(APIFinallyCallback cb) && + { + this->data_->finally = cb; + return std::move(*this); + }; + + void execute() + { + this->underlying_.execute(); + } +}; + +} // namespace chatterino