blob: d3f60fbfba24797656aa4579726331bc86347c0b [file] [log] [blame]
rohitpaic1a75eb2025-01-03 19:13:36 +05301#pragma once
2#include "async_resp.hpp"
Rohit PAIfdf51f52025-04-04 11:12:12 +05303#include "sub_request.hpp"
rohitpaic1a75eb2025-01-03 19:13:36 +05304
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
15namespace redfish
16{
17class OemBaseRule
18{
19 public:
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
Rohit PAIfdf51f52025-04-04 11:12:12 +053027 virtual void handle(const SubRequest& req,
rohitpaic1a75eb2025-01-03 19:13:36 +053028 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Rohit PAIfdf51f52025-04-04 11:12:12 +053029 const std::vector<std::string>& params) = 0;
rohitpaic1a75eb2025-01-03 19:13:36 +053030 std::string rule;
31};
32
33template <typename... Args>
34class OemRule : public OemBaseRule
35{
36 public:
37 using self_t = OemRule<Args...>;
38
39 explicit OemRule(std::string_view ruleIn) : OemBaseRule(ruleIn) {}
40
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>
51 void operator()(Func&& f)
52 {
53 static_assert(
Rohit PAIfdf51f52025-04-04 11:12:12 +053054 std::is_invocable_v<Func, SubRequest,
rohitpaic1a75eb2025-01-03 19:13:36 +053055 std::shared_ptr<bmcweb::AsyncResp>&, Args...>,
56 "Handler type is mismatched with URL parameters");
57 static_assert(
58 std::is_same_v<
Rohit PAIfdf51f52025-04-04 11:12:12 +053059 void, std::invoke_result_t<Func, SubRequest,
rohitpaic1a75eb2025-01-03 19:13:36 +053060 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
Rohit PAIfdf51f52025-04-04 11:12:12 +053067 void handle(const SubRequest& req,
rohitpaic1a75eb2025-01-03 19:13:36 +053068 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:
Rohit PAIfdf51f52025-04-04 11:12:12 +0530100 std::function<void(const SubRequest&,
rohitpaic1a75eb2025-01-03 19:13:36 +0530101 const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>
102 handler;
103};
104} // namespace redfish