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