AutoCatGnome/services/Api.cpp
2022-02-23 15:14:13 +03:00

79 lines
2.5 KiB
C++

//
// Created by selim on 03.01.2022.
//
#include "Api.h"
#include "Settings.h"
#include <memory>
template<class...Args>
struct Callback {
void(*function)(Args..., void*) = nullptr;
void* state = nullptr;
};
template<typename... Args, typename Lambda>
Callback<Args...> voidify(Lambda&& l) {
using Func = typename std::decay<Lambda>::type;
auto data = new Func(std::forward<Lambda>(l));
return {
+[](Args... args, void* v)->void {
Func* f = static_cast< Func* >(v);
(*f)(std::forward<Args>(args)...);
delete f;
},
data
};
}
const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/";
SoupSession* Api::_session = soup_session_new();
template<typename T>
boost::future<T> Api::post(const std::string &method, const nlohmann::json& params) {
std::string url = _baseUrl + method;
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
auto promise = std::make_shared<boost::promise<T>>();
auto callback = voidify<SoupSession*, SoupMessage*>([&, promise](SoupSession* session, SoupMessage* message) {
if(message->status_code >= 200 && message->status_code < 300) {
auto responseString = std::string(message->response_body->data, message->response_body->length);
auto json = nlohmann::json::parse(responseString);
if(json["success"].get<bool>()) {
std::cout << "response: " << responseString << std::endl;
auto user = json["data"].get<T>();
promise->set_value(user);
} else {
auto error = json["error"].get<std::string>();
promise->set_exception(FutureException(error));
}
} else {
promise->set_exception(FutureException(message->reason_phrase));
}
});
auto jsonStr = params.dump();
soup_message_set_request(msg, "application/json", SOUP_MEMORY_COPY, jsonStr.c_str(), jsonStr.size());
soup_session_queue_message(_session, msg, callback.function, callback.state);
return promise->get_future();
}
boost::future<User> Api::login(std::string email, std::string password) {
nlohmann::json params = {
{ "email", email },
{ "password", password }
};
auto user = Settings::instance().user();
auto result = co_await post<User>("user/login", params);
user.email = result.email;
user.token = result.token;
Settings::instance().setUser(user);
co_return user;
}