140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 308bbe119SEd Tanous #pragma once 408bbe119SEd Tanous 5*d7857201SEd Tanous #include "async_resp.hpp" 6*d7857201SEd Tanous #include "baserule.hpp" 7*d7857201SEd Tanous #include "http_request.hpp" 8*d7857201SEd Tanous #include "ruleparametertraits.hpp" 9*d7857201SEd Tanous 10*d7857201SEd Tanous #include <boost/callable_traits/args.hpp> 1108bbe119SEd Tanous 1208bbe119SEd Tanous #include <functional> 13*d7857201SEd Tanous #include <memory> 14*d7857201SEd Tanous #include <stdexcept> 1508bbe119SEd Tanous #include <string> 16*d7857201SEd Tanous #include <tuple> 17*d7857201SEd Tanous #include <vector> 1808bbe119SEd Tanous 1908bbe119SEd Tanous namespace crow 2008bbe119SEd Tanous { 2108bbe119SEd Tanous namespace detail 2208bbe119SEd Tanous { 2308bbe119SEd Tanous 2408bbe119SEd Tanous template <typename Func, typename... ArgsWrapped> 2508bbe119SEd Tanous struct Wrapped 261017ef80SEd Tanous {}; 271017ef80SEd Tanous 281017ef80SEd Tanous template <typename Func, typename... ArgsWrapped> 291017ef80SEd Tanous struct Wrapped<Func, std::tuple<ArgsWrapped...>> 3008bbe119SEd Tanous { Wrappedcrow::detail::Wrapped311017ef80SEd Tanous explicit Wrapped(Func f) : handler(std::move(f)) {} 3208bbe119SEd Tanous 33cfe3bc0aSEd Tanous std::function<void(ArgsWrapped...)> handler; 3408bbe119SEd Tanous operator ()crow::detail::Wrapped3508bbe119SEd Tanous void operator()(const Request& req, 3608bbe119SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3708bbe119SEd Tanous const std::vector<std::string>& params) 3808bbe119SEd Tanous { 39cfe3bc0aSEd Tanous if constexpr (sizeof...(ArgsWrapped) == 2) 40cfe3bc0aSEd Tanous { 41cfe3bc0aSEd Tanous handler(req, asyncResp); 42cfe3bc0aSEd Tanous } 43cfe3bc0aSEd Tanous else if constexpr (sizeof...(ArgsWrapped) == 3) 44cfe3bc0aSEd Tanous { 45cfe3bc0aSEd Tanous handler(req, asyncResp, params[0]); 46cfe3bc0aSEd Tanous } 47cfe3bc0aSEd Tanous else if constexpr (sizeof...(ArgsWrapped) == 4) 48cfe3bc0aSEd Tanous { 49cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1]); 50cfe3bc0aSEd Tanous } 51cfe3bc0aSEd Tanous else if constexpr (sizeof...(ArgsWrapped) == 5) 52cfe3bc0aSEd Tanous { 53cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2]); 54cfe3bc0aSEd Tanous } 55cfe3bc0aSEd Tanous else if constexpr (sizeof...(ArgsWrapped) == 6) 56cfe3bc0aSEd Tanous { 57cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2], params[3]); 58cfe3bc0aSEd Tanous } 59cfe3bc0aSEd Tanous else if constexpr (sizeof...(ArgsWrapped) == 7) 60cfe3bc0aSEd Tanous { 61cfe3bc0aSEd Tanous handler(req, asyncResp, params[0], params[1], params[2], params[3], 62cfe3bc0aSEd Tanous params[4]); 63cfe3bc0aSEd Tanous } 6408bbe119SEd Tanous } 6508bbe119SEd Tanous }; 6608bbe119SEd Tanous } // namespace detail 6708bbe119SEd Tanous 6808bbe119SEd Tanous class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> 6908bbe119SEd Tanous { 7008bbe119SEd Tanous public: DynamicRule(const std::string & ruleIn)7108bbe119SEd Tanous explicit DynamicRule(const std::string& ruleIn) : BaseRule(ruleIn) {} 7208bbe119SEd Tanous validate()7308bbe119SEd Tanous void validate() override 7408bbe119SEd Tanous { 7508bbe119SEd Tanous if (!erasedHandler) 7608bbe119SEd Tanous { 7708bbe119SEd Tanous throw std::runtime_error("no handler for url " + rule); 7808bbe119SEd Tanous } 7908bbe119SEd Tanous } 8008bbe119SEd Tanous handle(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)8108bbe119SEd Tanous void handle(const Request& req, 8208bbe119SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8308bbe119SEd Tanous const std::vector<std::string>& params) override 8408bbe119SEd Tanous { 8508bbe119SEd Tanous erasedHandler(req, asyncResp, params); 8608bbe119SEd Tanous } 8708bbe119SEd Tanous 8808bbe119SEd Tanous template <typename Func> operator ()(Func f)8908bbe119SEd Tanous void operator()(Func f) 9008bbe119SEd Tanous { 9108bbe119SEd Tanous using boost::callable_traits::args_t; 921017ef80SEd Tanous erasedHandler = detail::Wrapped<Func, args_t<Func>>(std::move(f)); 9308bbe119SEd Tanous } 9408bbe119SEd Tanous 9508bbe119SEd Tanous private: 9608bbe119SEd Tanous std::function<void(const Request&, 9708bbe119SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>&, 9808bbe119SEd Tanous const std::vector<std::string>&)> 9908bbe119SEd Tanous erasedHandler; 10008bbe119SEd Tanous }; 10108bbe119SEd Tanous 10208bbe119SEd Tanous } // namespace crow 103