| #pragma once |
| #include "async_resp.hpp" |
| #include "sub_request.hpp" |
| |
| #include <nlohmann/json.hpp> |
| |
| #include <functional> |
| #include <memory> |
| #include <stdexcept> |
| #include <string> |
| #include <string_view> |
| #include <type_traits> |
| #include <vector> |
| |
| 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<bmcweb::AsyncResp>& asyncResp, |
| const std::vector<std::string>& params) = 0; |
| std::string rule; |
| }; |
| |
| template <typename... Args> |
| class OemRule : public OemBaseRule |
| { |
| public: |
| using self_t = OemRule<Args...>; |
| |
| 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 <typename Func> |
| void operator()(Func&& f) |
| { |
| static_assert( |
| std::is_invocable_v<Func, SubRequest, |
| std::shared_ptr<bmcweb::AsyncResp>&, Args...>, |
| "Handler type is mismatched with URL parameters"); |
| static_assert( |
| std::is_same_v< |
| void, std::invoke_result_t<Func, SubRequest, |
| std::shared_ptr<bmcweb::AsyncResp>&, |
| Args...>>, |
| "Handler function with response argument should have void return type"); |
| |
| handler = std::forward<Func>(f); |
| } |
| |
| void handle(const SubRequest& req, |
| const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, |
| const std::vector<std::string>& 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<void(const SubRequest&, |
| const std::shared_ptr<bmcweb::AsyncResp>&, Args...)> |
| handler; |
| }; |
| } // namespace redfish |