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