1 #pragma once 2 #include "baserule.hpp" 3 #include "ruleparametertraits.hpp" 4 #include "websocket.hpp" 5 6 #include <boost/beast/http/verb.hpp> 7 8 #include <functional> 9 #include <limits> 10 #include <string> 11 #include <type_traits> 12 13 namespace crow 14 { 15 namespace detail 16 { 17 18 template <typename Func, typename... ArgsWrapped> 19 struct Wrapped 20 {}; 21 22 template <typename Func, typename... ArgsWrapped> 23 struct Wrapped<Func, std::tuple<ArgsWrapped...>> 24 { 25 explicit Wrapped(Func f) : handler(std::move(f)) {} 26 27 std::function<void(ArgsWrapped...)> handler; 28 29 void operator()(const Request& req, 30 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 31 const std::vector<std::string>& params) 32 { 33 if constexpr (sizeof...(ArgsWrapped) == 2) 34 { 35 handler(req, asyncResp); 36 } 37 else if constexpr (sizeof...(ArgsWrapped) == 3) 38 { 39 handler(req, asyncResp, params[0]); 40 } 41 else if constexpr (sizeof...(ArgsWrapped) == 4) 42 { 43 handler(req, asyncResp, params[0], params[1]); 44 } 45 else if constexpr (sizeof...(ArgsWrapped) == 5) 46 { 47 handler(req, asyncResp, params[0], params[1], params[2]); 48 } 49 else if constexpr (sizeof...(ArgsWrapped) == 6) 50 { 51 handler(req, asyncResp, params[0], params[1], params[2], params[3]); 52 } 53 else if constexpr (sizeof...(ArgsWrapped) == 7) 54 { 55 handler(req, asyncResp, params[0], params[1], params[2], params[3], 56 params[4]); 57 } 58 } 59 }; 60 } // namespace detail 61 62 class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule> 63 { 64 public: 65 explicit DynamicRule(const std::string& ruleIn) : BaseRule(ruleIn) {} 66 67 void validate() override 68 { 69 if (!erasedHandler) 70 { 71 throw std::runtime_error("no handler for url " + rule); 72 } 73 } 74 75 void handle(const Request& req, 76 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 77 const std::vector<std::string>& params) override 78 { 79 erasedHandler(req, asyncResp, params); 80 } 81 82 template <typename Func> 83 void operator()(Func f) 84 { 85 using boost::callable_traits::args_t; 86 erasedHandler = detail::Wrapped<Func, args_t<Func>>(std::move(f)); 87 } 88 89 private: 90 std::function<void(const Request&, 91 const std::shared_ptr<bmcweb::AsyncResp>&, 92 const std::vector<std::string>&)> 93 erasedHandler; 94 }; 95 96 } // namespace crow 97