1 #pragma once 2 #include "async_resp.hpp" 3 #include "sub_request.hpp" 4 5 #include <nlohmann/json.hpp> 6 7 #include <functional> 8 #include <memory> 9 #include <stdexcept> 10 #include <string> 11 #include <string_view> 12 #include <type_traits> 13 #include <vector> 14 15 namespace redfish 16 { 17 class OemBaseRule 18 { 19 public: OemBaseRule(std::string_view thisRule)20 explicit OemBaseRule(std::string_view thisRule) : rule(thisRule) {} 21 virtual ~OemBaseRule() = default; 22 OemBaseRule(const OemBaseRule&) = delete; 23 OemBaseRule(OemBaseRule&&) = delete; 24 OemBaseRule& operator=(const OemBaseRule&) = delete; 25 OemBaseRule& operator=(const OemBaseRule&&) = delete; 26 27 virtual void handle(const SubRequest& req, 28 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 29 const std::vector<std::string>& params) = 0; 30 std::string rule; 31 }; 32 33 template <typename... Args> 34 class OemRule : public OemBaseRule 35 { 36 public: 37 using self_t = OemRule<Args...>; 38 OemRule(std::string_view ruleIn)39 explicit OemRule(std::string_view ruleIn) : OemBaseRule(ruleIn) {} 40 validate()41 void validate() 42 { 43 if (!handler) 44 { 45 throw std::runtime_error( 46 "no OEM fragment handler for the rule {}" + rule); 47 } 48 } 49 50 template <typename Func> operator ()(Func && f)51 void operator()(Func&& f) 52 { 53 static_assert( 54 std::is_invocable_v<Func, SubRequest, 55 std::shared_ptr<bmcweb::AsyncResp>&, Args...>, 56 "Handler type is mismatched with URL parameters"); 57 static_assert( 58 std::is_same_v< 59 void, std::invoke_result_t<Func, SubRequest, 60 std::shared_ptr<bmcweb::AsyncResp>&, 61 Args...>>, 62 "Handler function with response argument should have void return type"); 63 64 handler = std::forward<Func>(f); 65 } 66 handle(const SubRequest & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)67 void handle(const SubRequest& req, 68 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 69 const std::vector<std::string>& params) override 70 { 71 if constexpr (sizeof...(Args) == 0) 72 { 73 handler(req, asyncResp); 74 } 75 else if constexpr (sizeof...(Args) == 1) 76 { 77 handler(req, asyncResp, params[0]); 78 } 79 else if constexpr (sizeof...(Args) == 2) 80 { 81 handler(req, asyncResp, params[0], params[1]); 82 } 83 else if constexpr (sizeof...(Args) == 3) 84 { 85 handler(req, asyncResp, params[0], params[1], params[2]); 86 } 87 else if constexpr (sizeof...(Args) == 4) 88 { 89 handler(req, asyncResp, params[0], params[1], params[2], params[3]); 90 } 91 else if constexpr (sizeof...(Args) == 5) 92 { 93 handler(req, asyncResp, params[0], params[1], params[2], params[3], 94 params[4]); 95 } 96 static_assert(sizeof...(Args) <= 5, "More args than are supported"); 97 } 98 99 private: 100 std::function<void(const SubRequest&, 101 const std::shared_ptr<bmcweb::AsyncResp>&, Args...)> 102 handler; 103 }; 104 } // namespace redfish 105