xref: /openbmc/bmcweb/http/routing/taggedrule.hpp (revision cfe3bc0a)
108bbe119SEd Tanous #pragma once
208bbe119SEd Tanous #include "baserule.hpp"
308bbe119SEd Tanous #include "dynamicrule.hpp"
408bbe119SEd Tanous #include "ruleparametertraits.hpp"
508bbe119SEd Tanous 
608bbe119SEd Tanous #include <boost/beast/http/verb.hpp>
708bbe119SEd Tanous 
808bbe119SEd Tanous #include <memory>
908bbe119SEd Tanous #include <string>
1008bbe119SEd Tanous #include <vector>
1108bbe119SEd Tanous 
1208bbe119SEd Tanous namespace crow
1308bbe119SEd Tanous {
1408bbe119SEd Tanous template <typename... Args>
1508bbe119SEd Tanous class TaggedRule :
1608bbe119SEd Tanous     public BaseRule,
1708bbe119SEd Tanous     public RuleParameterTraits<TaggedRule<Args...>>
1808bbe119SEd Tanous {
1908bbe119SEd Tanous   public:
2008bbe119SEd Tanous     using self_t = TaggedRule<Args...>;
2108bbe119SEd Tanous 
TaggedRule(const std::string & ruleIn)2208bbe119SEd Tanous     explicit TaggedRule(const std::string& ruleIn) : BaseRule(ruleIn) {}
2308bbe119SEd Tanous 
validate()2408bbe119SEd Tanous     void validate() override
2508bbe119SEd Tanous     {
2608bbe119SEd Tanous         if (!handler)
2708bbe119SEd Tanous         {
2808bbe119SEd Tanous             throw std::runtime_error("no handler for url " + rule);
2908bbe119SEd Tanous         }
3008bbe119SEd Tanous     }
3108bbe119SEd Tanous 
3208bbe119SEd Tanous     template <typename Func>
operator ()(Func && f)3308bbe119SEd Tanous     void operator()(Func&& f)
3408bbe119SEd Tanous     {
3508bbe119SEd Tanous         static_assert(
36*cfe3bc0aSEd Tanous             std::is_invocable_v<Func, crow::Request,
37*cfe3bc0aSEd Tanous                                 std::shared_ptr<bmcweb::AsyncResp>&, Args...>,
3808bbe119SEd Tanous             "Handler type is mismatched with URL parameters");
3908bbe119SEd Tanous         static_assert(
40*cfe3bc0aSEd Tanous             std::is_same_v<
41*cfe3bc0aSEd Tanous                 void, std::invoke_result_t<Func, crow::Request,
42*cfe3bc0aSEd Tanous                                            std::shared_ptr<bmcweb::AsyncResp>&,
43*cfe3bc0aSEd Tanous                                            Args...>>,
4408bbe119SEd Tanous             "Handler function with response argument should have void return type");
4508bbe119SEd Tanous 
4608bbe119SEd Tanous         handler = std::forward<Func>(f);
4708bbe119SEd Tanous     }
4808bbe119SEd Tanous 
handle(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)4908bbe119SEd Tanous     void handle(const Request& req,
5008bbe119SEd Tanous                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
5108bbe119SEd Tanous                 const std::vector<std::string>& params) override
5208bbe119SEd Tanous     {
53*cfe3bc0aSEd Tanous         if constexpr (sizeof...(Args) == 0)
54*cfe3bc0aSEd Tanous         {
55*cfe3bc0aSEd Tanous             handler(req, asyncResp);
56*cfe3bc0aSEd Tanous         }
57*cfe3bc0aSEd Tanous         else if constexpr (sizeof...(Args) == 1)
58*cfe3bc0aSEd Tanous         {
59*cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0]);
60*cfe3bc0aSEd Tanous         }
61*cfe3bc0aSEd Tanous         else if constexpr (sizeof...(Args) == 2)
62*cfe3bc0aSEd Tanous         {
63*cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1]);
64*cfe3bc0aSEd Tanous         }
65*cfe3bc0aSEd Tanous         else if constexpr (sizeof...(Args) == 3)
66*cfe3bc0aSEd Tanous         {
67*cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2]);
68*cfe3bc0aSEd Tanous         }
69*cfe3bc0aSEd Tanous         else if constexpr (sizeof...(Args) == 4)
70*cfe3bc0aSEd Tanous         {
71*cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2], params[3]);
72*cfe3bc0aSEd Tanous         }
73*cfe3bc0aSEd Tanous         else if constexpr (sizeof...(Args) == 5)
74*cfe3bc0aSEd Tanous         {
75*cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2], params[3],
76*cfe3bc0aSEd Tanous                     params[4]);
77*cfe3bc0aSEd Tanous         }
78*cfe3bc0aSEd Tanous         static_assert(sizeof...(Args) <= 5, "More args than are supported");
7908bbe119SEd Tanous     }
8008bbe119SEd Tanous 
8108bbe119SEd Tanous   private:
8208bbe119SEd Tanous     std::function<void(const crow::Request&,
8308bbe119SEd Tanous                        const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>
8408bbe119SEd Tanous         handler;
8508bbe119SEd Tanous };
8608bbe119SEd Tanous } // namespace crow
87