1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #pragma once 4 #include "baserule.hpp" 5 #include "dynamicrule.hpp" 6 #include "ruleparametertraits.hpp" 7 8 #include <boost/beast/http/verb.hpp> 9 10 #include <memory> 11 #include <string> 12 #include <vector> 13 14 namespace crow 15 { 16 template <typename... Args> 17 class TaggedRule : 18 public BaseRule, 19 public RuleParameterTraits<TaggedRule<Args...>> 20 { 21 public: 22 using self_t = TaggedRule<Args...>; 23 24 explicit TaggedRule(const std::string& ruleIn) : BaseRule(ruleIn) {} 25 26 void validate() override 27 { 28 if (!handler) 29 { 30 throw std::runtime_error("no handler for url " + rule); 31 } 32 } 33 34 template <typename Func> 35 void operator()(Func&& f) 36 { 37 static_assert( 38 std::is_invocable_v<Func, crow::Request, 39 std::shared_ptr<bmcweb::AsyncResp>&, Args...>, 40 "Handler type is mismatched with URL parameters"); 41 static_assert( 42 std::is_same_v< 43 void, std::invoke_result_t<Func, crow::Request, 44 std::shared_ptr<bmcweb::AsyncResp>&, 45 Args...>>, 46 "Handler function with response argument should have void return type"); 47 48 handler = std::forward<Func>(f); 49 } 50 51 void handle(const Request& req, 52 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 53 const std::vector<std::string>& params) override 54 { 55 if constexpr (sizeof...(Args) == 0) 56 { 57 handler(req, asyncResp); 58 } 59 else if constexpr (sizeof...(Args) == 1) 60 { 61 handler(req, asyncResp, params[0]); 62 } 63 else if constexpr (sizeof...(Args) == 2) 64 { 65 handler(req, asyncResp, params[0], params[1]); 66 } 67 else if constexpr (sizeof...(Args) == 3) 68 { 69 handler(req, asyncResp, params[0], params[1], params[2]); 70 } 71 else if constexpr (sizeof...(Args) == 4) 72 { 73 handler(req, asyncResp, params[0], params[1], params[2], params[3]); 74 } 75 else if constexpr (sizeof...(Args) == 5) 76 { 77 handler(req, asyncResp, params[0], params[1], params[2], params[3], 78 params[4]); 79 } 80 static_assert(sizeof...(Args) <= 5, "More args than are supported"); 81 } 82 83 private: 84 std::function<void(const crow::Request&, 85 const std::shared_ptr<bmcweb::AsyncResp>&, Args...)> 86 handler; 87 }; 88 } // namespace crow 89