#pragma once #include "async_resp.hpp" #include "sub_request.hpp" #include #include #include #include #include #include #include #include namespace redfish { class OemBaseRule { public: explicit OemBaseRule(std::string_view thisRule) : rule(thisRule) {} virtual ~OemBaseRule() = default; OemBaseRule(const OemBaseRule&) = delete; OemBaseRule(OemBaseRule&&) = delete; OemBaseRule& operator=(const OemBaseRule&) = delete; OemBaseRule& operator=(const OemBaseRule&&) = delete; virtual void handle(const SubRequest& req, const std::shared_ptr& asyncResp, const std::vector& params) = 0; std::string rule; }; template class OemRule : public OemBaseRule { public: using self_t = OemRule; explicit OemRule(std::string_view ruleIn) : OemBaseRule(ruleIn) {} void validate() { if (!handler) { throw std::runtime_error( "no OEM fragment handler for the rule {}" + rule); } } template void operator()(Func&& f) { static_assert( std::is_invocable_v&, Args...>, "Handler type is mismatched with URL parameters"); static_assert( std::is_same_v< void, std::invoke_result_t&, Args...>>, "Handler function with response argument should have void return type"); handler = std::forward(f); } void handle(const SubRequest& req, const std::shared_ptr& asyncResp, const std::vector& params) override { if constexpr (sizeof...(Args) == 0) { handler(req, asyncResp); } else if constexpr (sizeof...(Args) == 1) { handler(req, asyncResp, params[0]); } else if constexpr (sizeof...(Args) == 2) { handler(req, asyncResp, params[0], params[1]); } else if constexpr (sizeof...(Args) == 3) { handler(req, asyncResp, params[0], params[1], params[2]); } else if constexpr (sizeof...(Args) == 4) { handler(req, asyncResp, params[0], params[1], params[2], params[3]); } else if constexpr (sizeof...(Args) == 5) { handler(req, asyncResp, params[0], params[1], params[2], params[3], params[4]); } static_assert(sizeof...(Args) <= 5, "More args than are supported"); } private: std::function&, Args...)> handler; }; } // namespace redfish