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) { client(client) {
this->AddHeader("User-Agent", "cserver/1"); this->AddHeader("User-Agent", "cserver/1");
}; };
inline constexpr auto Post() && -> Request<HttpClient>&& { inline constexpr auto Post(this auto&& self) -> decltype(auto) {
this->request.method = "POST"; self.request.method = "POST";
return std::move(*this); return self;
}; };
inline constexpr auto Post() & -> Request<HttpClient>& { inline constexpr auto Get(this auto&& self) -> decltype(auto) {
this->request.method = "POST"; self.request.method = "GET";
return *this; return self;
}; };
inline constexpr auto Get() && -> Request<HttpClient>&& { inline constexpr auto Put(this auto&& self) -> decltype(auto) {
this->request.method = "GET"; self.request.method = "PUT";
return std::move(*this); return self;
}; };
inline constexpr auto Get() & -> Request<HttpClient>& { inline constexpr auto SetCustomMethod(this auto&& self, std::string method) -> decltype(auto) {
this->request.method = "GET"; self.request.method = std::move(method);
return *this; return self;
}; };
inline constexpr auto Put() && -> Request<HttpClient>&& { inline constexpr auto AddHeader(this auto&& self, std::string first, std::string second) -> decltype(auto) {
this->request.method = "PUT"; self.request.headers.emplace(std::move(first), std::move(second));
return std::move(*this); return self;
}; };
inline constexpr auto Put() & -> Request<HttpClient>& { template <typename Self>
this->request.method = "PUT"; inline constexpr auto AddHeaderIfNotExists(this Self&& self,
return *this; 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));
}; };
inline constexpr auto SetCustomMethod(std::string method) & -> Request<HttpClient>& { return self;
this->request.method = std::move(method);
return *this;
}; };
inline constexpr auto SetCustomMethod(std::string method) && -> Request<HttpClient>&& { template <typename Self>
this->request.method = std::move(method); inline constexpr auto Url(this Self&& self,
return std::move(*this); 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 AddHeader(std::string first, std::string second) && -> Request<HttpClient>&& { inline constexpr auto Data(this auto&& self, std::string data) -> decltype(auto) {
this->request.headers.emplace(std::move(first), std::move(second)); self.request.body = std::move(data);
return std::move(*this); return self;
};
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));
};
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 std::move(*this).AddHeader(std::move(first), std::move(second));
};
return std::move(*this);
};
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 ToString() const -> std::string { inline constexpr auto ToString() const -> std::string {
return this->request.ToString(); return this->request.ToString();
}; };
template <typename... Flags> template <typename Self, typename... Flags>
inline auto Perform(Flags&&... flags) && inline auto Perform(this Self&& self, 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)...)) { -> decltype(self.client.PerformRequest(std::forward<Self>(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::to_string(self.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)...); HttpClient& client = self.client;
}; std::string size = std::to_string(self.request.body.size());
template <typename... Flags> co_return co_await client.PerformRequest(std::forward<Self>(self).AddHeaderIfNotExists("Transfer-Encoding", "Content-Length", std::move(size)), std::forward<Flags>(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)...);
}; };
}; };
}; };

View file

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