From 328f8930e80068bf0b04411f5ca2b1e4702f8515 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 8 Feb 2019 21:13:13 +0000 Subject: Properly generic parameter extraction --- icespider/core/ihttpRequest.cpp | 48 ++++++----------------------------------- icespider/core/ihttpRequest.h | 47 +++++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp index aaa0c26..b8d866a 100644 --- a/icespider/core/ihttpRequest.cpp +++ b/icespider/core/ihttpRequest.cpp @@ -103,8 +103,8 @@ namespace IceSpider { } } - const std::string & - IHttpRequest::getURLParam(unsigned int idx) const + OptionalString + IHttpRequest::getURLParam(const unsigned int & idx) const { auto & url = getRequestPath(); if (idx >= url.size()) { @@ -170,45 +170,9 @@ namespace IceSpider { s.second->Serialize(mp); } - std::optional - operator!(const std::optional & sv) - { - // TODO: Fix this mess (only required if operation requires std::string) - if (sv) return { std::string(*sv) }; - return {}; - } - -#define getParams(T) \ - template<> T IHttpRequest::getURLParam(unsigned int idx) const { \ - return wrapLexicalCast(getURLParam(idx)); } \ - template<> std::optional IHttpRequest::getQueryStringParam(const std::string_view & key) const { \ - return optionalLexicalCast(getQueryStringParam(key)); } \ - template<> std::optional IHttpRequest::getCookieParam(const std::string_view & key) const { \ - return optionalLexicalCast(getCookieParam(key)); } \ - template<> std::optional IHttpRequest::getHeaderParam(const std::string_view & key) const { \ - return optionalLexicalCast(getHeaderParam(key)); } - template<> std::string_view IHttpRequest::getURLParam(unsigned int idx) const { - return getURLParam(idx); } - template<> OptionalString IHttpRequest::getQueryStringParam(const std::string_view & key) const { \ - return getQueryStringParam(key); } - template<> OptionalString IHttpRequest::getCookieParam(const std::string_view & key) const { \ - return getCookieParam(key); } - template<> OptionalString IHttpRequest::getHeaderParam(const std::string_view & key) const { \ - return getHeaderParam(key); } - template<> std::string IHttpRequest::getURLParam(unsigned int idx) const { - return getURLParam(idx); } - template<> std::optional IHttpRequest::getQueryStringParam(const std::string_view & key) const { \ - return !getQueryStringParam(key); } - template<> std::optional IHttpRequest::getCookieParam(const std::string_view & key) const { \ - return !getCookieParam(key); } - template<> std::optional IHttpRequest::getHeaderParam(const std::string_view & key) const { \ - return !getHeaderParam(key); } - - getParams(bool); - getParams(Ice::Short); - getParams(Ice::Int); - getParams(Ice::Long); - getParams(Ice::Float); - getParams(Ice::Double); + static_assert(std::is_convertible::value); + static_assert(!std::is_convertible::value); + static_assert(std::is_constructible::value); } + diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h index 5471209..fb56efb 100644 --- a/icespider/core/ihttpRequest.h +++ b/icespider/core/ihttpRequest.h @@ -9,6 +9,7 @@ #include #include #include +#include "exceptions.h" namespace IceSpider { class Core; @@ -27,7 +28,7 @@ namespace IceSpider { virtual PathElements & getRequestPath() = 0; virtual HttpMethod getRequestMethod() const = 0; - const std::string & getURLParam(unsigned int) const; + OptionalString getURLParam(const unsigned int &) const; virtual OptionalString getQueryStringParam(const std::string_view &) const = 0; virtual OptionalString getHeaderParam(const std::string_view &) const = 0; virtual OptionalString getCookieParam(const std::string_view &) const = 0; @@ -41,8 +42,35 @@ namespace IceSpider { virtual std::ostream & dump(std::ostream & s) const = 0; + template + inline + std::optional getFrom(const K & key, OptionalString (IHttpRequest::*src)(const K &) const) const + { + if (auto v = (this->*src)(key)) { + if constexpr (std::is_convertible::value) { + return *v; + } + else if constexpr (std::is_constructible::value) { + return T(*v); + } + else { + try { + return boost::lexical_cast(*v); + } + catch (const boost::bad_lexical_cast & e) { + throw Http400_BadRequest(); + } + } + } + else { + return std::nullopt; + } + } template - T getURLParam(unsigned int) const; + T getURLParam(unsigned int n) const + { + return *getFrom(n, &IHttpRequest::getURLParam); + } template std::optional getBody() const { @@ -79,11 +107,20 @@ namespace IceSpider { } } template - std::optional getQueryStringParam(const std::string_view & key) const; + std::optional getQueryStringParam(const std::string_view & key) const + { + return getFrom(key, &IHttpRequest::getQueryStringParam); + } template - std::optional getHeaderParam(const std::string_view & key) const; + std::optional getHeaderParam(const std::string_view & key) const + { + return getFrom(key, &IHttpRequest::getHeaderParam); + } template - std::optional getCookieParam(const std::string_view & key) const; + std::optional getCookieParam(const std::string_view & key) const + { + return getFrom(key, &IHttpRequest::getCookieParam); + } virtual void response(short, const std::string_view &) const = 0; template void response(const IRouteHandler * route, const T & t) const -- cgit v1.2.3