xref: /openbmc/bmcweb/http/routing/taggedrule.hpp (revision 08bbe119)
1 #pragma once
2 #include "baserule.hpp"
3 #include "dynamicrule.hpp"
4 #include "ruleparametertraits.hpp"
5 
6 #include <boost/beast/http/verb.hpp>
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 namespace crow
13 {
14 template <typename... Args>
15 class TaggedRule :
16     public BaseRule,
17     public RuleParameterTraits<TaggedRule<Args...>>
18 {
19   public:
20     using self_t = TaggedRule<Args...>;
21 
22     explicit TaggedRule(const std::string& ruleIn) : BaseRule(ruleIn) {}
23 
24     void validate() override
25     {
26         if (!handler)
27         {
28             throw std::runtime_error("no handler for url " + rule);
29         }
30     }
31 
32     template <typename Func>
33     void operator()(Func&& f)
34     {
35         static_assert(
36             black_magic::CallHelper<
37                 Func, black_magic::S<crow::Request,
38                                      std::shared_ptr<bmcweb::AsyncResp>&,
39                                      Args...>>::value,
40             "Handler type is mismatched with URL parameters");
41         static_assert(
42             std::is_same<
43                 void,
44                 decltype(f(std::declval<crow::Request>(),
45                            std::declval<std::shared_ptr<bmcweb::AsyncResp>&>(),
46                            std::declval<Args>()...))>::value,
47             "Handler function with response argument should have void return type");
48 
49         handler = std::forward<Func>(f);
50     }
51 
52     void handle(const Request& req,
53                 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
54                 const std::vector<std::string>& params) override
55     {
56         detail::routing_handler_call_helper::Call<
57             detail::routing_handler_call_helper::CallParams<decltype(handler)>,
58             0, black_magic::S<Args...>, black_magic::S<>>()(
59             detail::routing_handler_call_helper::CallParams<decltype(handler)>{
60                 handler, params, req, asyncResp});
61     }
62 
63   private:
64     std::function<void(const crow::Request&,
65                        const std::shared_ptr<bmcweb::AsyncResp>&, Args...)>
66         handler;
67 };
68 } // namespace crow
69