Use deduction this

This commit is contained in:
sha512sum 2024-03-14 21:00:06 +00:00
parent f3e8ff5d73
commit 84c562f45d
2 changed files with 50 additions and 74 deletions

View file

@ -12,85 +12,58 @@ struct Request {
client(client) {
this->AddHeader("User-Agent", "cserver/1");
};
inline constexpr auto Post() && -> Request<HttpClient>&& {
this->request.method = "POST";
return std::move(*this);
inline constexpr auto Post(this auto&& self) -> decltype(auto) {
self.request.method = "POST";
return self;
};
inline constexpr auto Post() & -> Request<HttpClient>& {
this->request.method = "POST";
return *this;
inline constexpr auto Get(this auto&& self) -> decltype(auto) {
self.request.method = "GET";
return self;
};
inline constexpr auto Get() && -> Request<HttpClient>&& {
this->request.method = "GET";
return std::move(*this);
inline constexpr auto Put(this auto&& self) -> decltype(auto) {
self.request.method = "PUT";
return self;
};
inline constexpr auto Get() & -> Request<HttpClient>& {
this->request.method = "GET";
return *this;
inline constexpr auto SetCustomMethod(this auto&& self, std::string method) -> decltype(auto) {
self.request.method = std::move(method);
return self;
};
inline constexpr auto Put() && -> Request<HttpClient>&& {
this->request.method = "PUT";
return std::move(*this);
inline constexpr auto AddHeader(this auto&& self, std::string first, std::string second) -> decltype(auto) {
self.request.headers.emplace(std::move(first), std::move(second));
return self;
};
inline constexpr auto Put() & -> Request<HttpClient>& {
this->request.method = "PUT";
return *this;
};
inline constexpr auto SetCustomMethod(std::string method) & -> Request<HttpClient>& {
this->request.method = std::move(method);
return *this;
};
inline constexpr auto SetCustomMethod(std::string method) && -> Request<HttpClient>&& {
this->request.method = std::move(method);
return std::move(*this);
};
inline constexpr auto AddHeader(std::string first, std::string second) && -> Request<HttpClient>&& {
this->request.headers.emplace(std::move(first), std::move(second));
return std::move(*this);
};
inline constexpr auto AddHeader(std::string first, std::string second) & -> Request<HttpClient>& {
this->request.headers.emplace(std::move(first), std::move(second));
return *this;
};
inline constexpr auto AddHeaderIfNotExists(std::string check, std::string first, std::string second) & -> Request<HttpClient>& {
if(!this->request.headers.contains(std::move(check))) {
return this->AddHeader(std::move(first), std::move(second));
template <typename Self>
inline constexpr auto AddHeaderIfNotExists(this Self&& self,
std::string check,
std::string first,
std::string second) -> decltype(auto) {
if(!self.request.headers.contains(std::move(check))) {
return std::forward<Self>(self).AddHeader(std::move(first), std::move(second));
};
return *this;
return self;
};
inline constexpr auto AddHeaderIfNotExists(std::string check, std::string first, std::string second) && -> Request<HttpClient>&& {
if(!this->request.headers.contains(std::move(check))) {
return std::move(*this).AddHeader(std::move(first), std::move(second));
};
return std::move(*this);
template <typename Self>
inline constexpr auto Url(this Self&& self,
std::string url) -> auto&& {
self.request.url = boost::urls::url{std::move(url)};
auto authority = self.request.url.authority();
return std::forward<Self>(self).AddHeader("Host", std::string{authority.data(), authority.size()});
};
inline constexpr auto Url(std::string url) & -> Request<HttpClient>& {
this->request.url = boost::urls::url{std::move(url)};
auto authority = this->request.url.authority();
return this->AddHeader("Host", std::string{authority.data(), authority.size()});
};
inline constexpr auto Url(std::string url) && -> Request<HttpClient>&& {
this->request.url = boost::urls::url{std::move(url)};
auto authority = this->request.url.authority();
return std::move(*this).AddHeader("Host", std::string{authority.data(), authority.size()});
};
inline constexpr auto Data(std::string data) && -> Request<HttpClient>&& {
this->request.body = std::move(data);
return std::move(*this);
inline constexpr auto Data(this auto&& self, std::string data) -> decltype(auto) {
self.request.body = std::move(data);
return self;
};
inline constexpr auto ToString() const -> std::string {
return this->request.ToString();
};
template <typename... Flags>
inline auto Perform(Flags&&... flags) &&
-> decltype(this->client.PerformRequest(std::move(*this).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(this->request.body.size())), std::forward<Flags>(flags)...)) {
co_return co_await this->client.PerformRequest(std::move(*this).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(this->request.body.size())), std::forward<Flags>(flags)...);
};
template <typename... Flags>
inline auto Perform(Flags&&... flags) &
-> decltype(this->client.PerformRequest(this->AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(this->request.body.size())), std::forward<Flags>(flags)...)) {
co_return co_await this->client.PerformRequest(this->AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(this->request.body.size())), std::forward<Flags>(flags)...);
template <typename Self, typename... Flags>
inline auto Perform(this Self&& self, Flags&&... flags)
-> decltype(self.client.PerformRequest(std::forward<Self>(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(self.request.body.size())), std::forward<Flags>(flags)...)) {
HttpClient& client = self.client;
std::string size = std::to_string(self.request.body.size());
co_return co_await client.PerformRequest(std::forward<Self>(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::move(size)), std::forward<Flags>(flags)...);
};
};
};

View file

@ -7,18 +7,19 @@
namespace cserver::server::handlers {
template <typename T>
struct HTTPHandlerBase {
template <utempl::ConstexprString name>
template <typename T, utempl::ConstexprString name>
static consteval auto Adder(const auto& context) {
return context.TransformComponents([]<typename TT>(const ComponentConfig<T::kHandlerManagerName, TT>) {
return ComponentConfig<T::kHandlerManagerName, typename TT::template AddHandler<ComponentConfig<name, T>>>{};
});
};
inline auto HandleRequest(cserver::server::http::HTTPRequest&& request,
cserver::server::http::HTTPResponse& response) -> Task<std::string> requires requires(T t) {t.HandleRequestThrow(std::move(request), response);} {
template <typename Self>
inline auto HandleRequest(this Self&& self, cserver::server::http::HTTPRequest&& request,
cserver::server::http::HTTPResponse& response) -> Task<std::string> requires requires{self.HandleRequestThrow(std::move(request), response);} {
using T = std::remove_cvref_t<Self>;
try {
co_return co_await static_cast<T&>(*this).HandleRequestThrow(std::move(request), response);
co_return co_await std::forward<Self>(self).HandleRequestThrow(std::move(request), response);
} catch(const std::exception& err) {
fmt::println("Error in handler with default name {}: {}", T::kName, err.what());
} catch(...) {
@ -28,10 +29,12 @@ struct HTTPHandlerBase {
response.statusMessage = "Internal Server Error";
co_return "Internal Server Error";
};
inline auto HandleRequestStream(cserver::server::http::HTTPRequest&& request,
cserver::server::http::HTTPStream& stream) -> Task<void> requires requires(T t) {t.HandleRequestStreamThrow(std::move(request), stream);} {
template <typename Self>
inline auto HandleRequestStream(this Self&& self, cserver::server::http::HTTPRequest&& request,
cserver::server::http::HTTPStream& stream) -> Task<void> requires requires{self.HandleRequestStreamThrow(std::move(request), stream);} {
using T = std::remove_cvref_t<Self>;
try {
co_await static_cast<T&>(*this).HandleRequestStreamThrow(std::move(request), stream);
co_await std::forward<Self>(self).HandleRequestStreamThrow(std::move(request), stream);
} catch(const std::exception& err) {
fmt::println("Error in handler with default name {}: {}", T::kName, err.what());
} catch(...) {