108bbe119SEd Tanous #pragma once 208bbe119SEd Tanous #include "baserule.hpp" 308bbe119SEd Tanous #include "dynamicrule.hpp" 408bbe119SEd Tanous #include "ruleparametertraits.hpp" 508bbe119SEd Tanous 608bbe119SEd Tanous #include <boost/beast/http/verb.hpp> 708bbe119SEd Tanous 808bbe119SEd Tanous #include <memory> 908bbe119SEd Tanous #include <string> 1008bbe119SEd Tanous #include <vector> 1108bbe119SEd Tanous 1208bbe119SEd Tanous namespace crow 1308bbe119SEd Tanous { 1408bbe119SEd Tanous template <typename... Args> 1508bbe119SEd Tanous class TaggedRule : 1608bbe119SEd Tanous public BaseRule, 1708bbe119SEd Tanous public RuleParameterTraits<TaggedRule<Args...>> 1808bbe119SEd Tanous { 1908bbe119SEd Tanous public: 2008bbe119SEd Tanous using self_t = TaggedRule<Args...>; 2108bbe119SEd Tanous TaggedRule(const std::string & ruleIn)2208bbe119SEd Tanous explicit TaggedRule(const std::string& ruleIn) : BaseRule(ruleIn) {} 2308bbe119SEd Tanous validate()2408bbe119SEd Tanous void validate() override 2508bbe119SEd Tanous { 2608bbe119SEd Tanous if (!handler) 2708bbe119SEd Tanous { 2808bbe119SEd Tanous throw std::runtime_error("no handler for url " + rule); 2908bbe119SEd Tanous } 3008bbe119SEd Tanous } 3108bbe119SEd Tanous 3208bbe119SEd Tanous template <typename Func> operator ()(Func && f)3308bbe119SEd Tanous void operator()(Func&& f) 3408bbe119SEd Tanous { 3508bbe119SEd Tanous static_assert( 36*cfe3bc0aSEd Tanous std::is_invocable_v<Func, crow::Request, 37*cfe3bc0aSEd Tanous std::shared_ptr<bmcweb::AsyncResp>&, Args...>, 3808bbe119SEd Tanous "Handler type is mismatched with URL parameters"); 3908bbe119SEd Tanous static_assert( 40*cfe3bc0aSEd Tanous std::is_same_v< 41*cfe3bc0aSEd Tanous void, std::invoke_result_t<Func, crow::Request, 42*cfe3bc0aSEd Tanous std::shared_ptr<bmcweb::AsyncResp>&, 43*cfe3bc0aSEd Tanous Args...>>, 4408bbe119SEd Tanous "Handler function with response argument should have void return type"); 4508bbe119SEd Tanous 4608bbe119SEd Tanous handler = std::forward<Func>(f); 4708bbe119SEd Tanous } 4808bbe119SEd Tanous handle(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)4908bbe119SEd Tanous void handle(const Request& req, 5008bbe119SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 5108bbe119SEd Tanous const std::vector<std::string>& params) override 5208bbe119SEd Tanous { 53*cfe3bc0aSEd Tanous if constexpr (sizeof...(Args) == 0) 54*cfe3bc0aSEd Tanous { 55*cfe3bc0aSEd Tanous handler(req, asyncResp); 56*cfe3bc0aSEd Tanous } 57*cfe3bc0aSEd Tanous else if constexpr (sizeof...(Args) == 1) 58*cfe3bc0aSEd Tanous { 59*cfe3bc0aSEd Tanous handler(req, asyncResp, params[0]); 60*cfe3bc0aSEd Tanous } 61*cfe3bc0aSEd Tanous else if constexpr (sizeof...(Args) == 2) 62*cfe3bc0aSEd Tanous { 63*cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1]); 64*cfe3bc0aSEd Tanous } 65*cfe3bc0aSEd Tanous else if constexpr (sizeof...(Args) == 3) 66*cfe3bc0aSEd Tanous { 67*cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2]); 68*cfe3bc0aSEd Tanous } 69*cfe3bc0aSEd Tanous else if constexpr (sizeof...(Args) == 4) 70*cfe3bc0aSEd Tanous { 71*cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2], params[3]); 72*cfe3bc0aSEd Tanous } 73*cfe3bc0aSEd Tanous else if constexpr (sizeof...(Args) == 5) 74*cfe3bc0aSEd Tanous { 75*cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2], params[3], 76*cfe3bc0aSEd Tanous params[4]); 77*cfe3bc0aSEd Tanous } 78*cfe3bc0aSEd Tanous static_assert(sizeof...(Args) <= 5, "More args than are supported"); 7908bbe119SEd Tanous } 8008bbe119SEd Tanous 8108bbe119SEd Tanous private: 8208bbe119SEd Tanous std::function<void(const crow::Request&, 8308bbe119SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>&, Args...)> 8408bbe119SEd Tanous handler; 8508bbe119SEd Tanous }; 8608bbe119SEd Tanous } // namespace crow 87