xref: /openbmc/bmcweb/http/routing/dynamicrule.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
308bbe119SEd Tanous #pragma once
408bbe119SEd Tanous 
5*d7857201SEd Tanous #include "async_resp.hpp"
6*d7857201SEd Tanous #include "baserule.hpp"
7*d7857201SEd Tanous #include "http_request.hpp"
8*d7857201SEd Tanous #include "ruleparametertraits.hpp"
9*d7857201SEd Tanous 
10*d7857201SEd Tanous #include <boost/callable_traits/args.hpp>
1108bbe119SEd Tanous 
1208bbe119SEd Tanous #include <functional>
13*d7857201SEd Tanous #include <memory>
14*d7857201SEd Tanous #include <stdexcept>
1508bbe119SEd Tanous #include <string>
16*d7857201SEd Tanous #include <tuple>
17*d7857201SEd Tanous #include <vector>
1808bbe119SEd Tanous 
1908bbe119SEd Tanous namespace crow
2008bbe119SEd Tanous {
2108bbe119SEd Tanous namespace detail
2208bbe119SEd Tanous {
2308bbe119SEd Tanous 
2408bbe119SEd Tanous template <typename Func, typename... ArgsWrapped>
2508bbe119SEd Tanous struct Wrapped
261017ef80SEd Tanous {};
271017ef80SEd Tanous 
281017ef80SEd Tanous template <typename Func, typename... ArgsWrapped>
291017ef80SEd Tanous struct Wrapped<Func, std::tuple<ArgsWrapped...>>
3008bbe119SEd Tanous {
Wrappedcrow::detail::Wrapped311017ef80SEd Tanous     explicit Wrapped(Func f) : handler(std::move(f)) {}
3208bbe119SEd Tanous 
33cfe3bc0aSEd Tanous     std::function<void(ArgsWrapped...)> handler;
3408bbe119SEd Tanous 
operator ()crow::detail::Wrapped3508bbe119SEd Tanous     void operator()(const Request& req,
3608bbe119SEd Tanous                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3708bbe119SEd Tanous                     const std::vector<std::string>& params)
3808bbe119SEd Tanous     {
39cfe3bc0aSEd Tanous         if constexpr (sizeof...(ArgsWrapped) == 2)
40cfe3bc0aSEd Tanous         {
41cfe3bc0aSEd Tanous             handler(req, asyncResp);
42cfe3bc0aSEd Tanous         }
43cfe3bc0aSEd Tanous         else if constexpr (sizeof...(ArgsWrapped) == 3)
44cfe3bc0aSEd Tanous         {
45cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0]);
46cfe3bc0aSEd Tanous         }
47cfe3bc0aSEd Tanous         else if constexpr (sizeof...(ArgsWrapped) == 4)
48cfe3bc0aSEd Tanous         {
49cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1]);
50cfe3bc0aSEd Tanous         }
51cfe3bc0aSEd Tanous         else if constexpr (sizeof...(ArgsWrapped) == 5)
52cfe3bc0aSEd Tanous         {
53cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2]);
54cfe3bc0aSEd Tanous         }
55cfe3bc0aSEd Tanous         else if constexpr (sizeof...(ArgsWrapped) == 6)
56cfe3bc0aSEd Tanous         {
57cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2], params[3]);
58cfe3bc0aSEd Tanous         }
59cfe3bc0aSEd Tanous         else if constexpr (sizeof...(ArgsWrapped) == 7)
60cfe3bc0aSEd Tanous         {
61cfe3bc0aSEd Tanous             handler(req, asyncResp, params[0], params[1], params[2], params[3],
62cfe3bc0aSEd Tanous                     params[4]);
63cfe3bc0aSEd Tanous         }
6408bbe119SEd Tanous     }
6508bbe119SEd Tanous };
6608bbe119SEd Tanous } // namespace detail
6708bbe119SEd Tanous 
6808bbe119SEd Tanous class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
6908bbe119SEd Tanous {
7008bbe119SEd Tanous   public:
DynamicRule(const std::string & ruleIn)7108bbe119SEd Tanous     explicit DynamicRule(const std::string& ruleIn) : BaseRule(ruleIn) {}
7208bbe119SEd Tanous 
validate()7308bbe119SEd Tanous     void validate() override
7408bbe119SEd Tanous     {
7508bbe119SEd Tanous         if (!erasedHandler)
7608bbe119SEd Tanous         {
7708bbe119SEd Tanous             throw std::runtime_error("no handler for url " + rule);
7808bbe119SEd Tanous         }
7908bbe119SEd Tanous     }
8008bbe119SEd Tanous 
handle(const Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::vector<std::string> & params)8108bbe119SEd Tanous     void handle(const Request& req,
8208bbe119SEd Tanous                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8308bbe119SEd Tanous                 const std::vector<std::string>& params) override
8408bbe119SEd Tanous     {
8508bbe119SEd Tanous         erasedHandler(req, asyncResp, params);
8608bbe119SEd Tanous     }
8708bbe119SEd Tanous 
8808bbe119SEd Tanous     template <typename Func>
operator ()(Func f)8908bbe119SEd Tanous     void operator()(Func f)
9008bbe119SEd Tanous     {
9108bbe119SEd Tanous         using boost::callable_traits::args_t;
921017ef80SEd Tanous         erasedHandler = detail::Wrapped<Func, args_t<Func>>(std::move(f));
9308bbe119SEd Tanous     }
9408bbe119SEd Tanous 
9508bbe119SEd Tanous   private:
9608bbe119SEd Tanous     std::function<void(const Request&,
9708bbe119SEd Tanous                        const std::shared_ptr<bmcweb::AsyncResp>&,
9808bbe119SEd Tanous                        const std::vector<std::string>&)>
9908bbe119SEd Tanous         erasedHandler;
10008bbe119SEd Tanous };
10108bbe119SEd Tanous 
10208bbe119SEd Tanous } // namespace crow
103