Kagome
Polkadot Runtime Engine in C++17
base_request.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_CHAIN_BASE_REQUEST_HPP
7 #define KAGOME_CHAIN_BASE_REQUEST_HPP
8 
9 #include <jsonrpc-lean/request.h>
10 #include <functional>
11 #include <optional>
12 #include <tuple>
13 
14 #include "outcome/outcome.hpp"
15 
17 
18  template <size_t I, size_t Max, typename Tuple, typename F>
19  constexpr void loop(Tuple &t, F &&f) {
20  static_assert(I <= Max, "Invalid expression!");
21  if constexpr (!std::equal_to<size_t>()(I, Max)) {
22  std::forward<F>(f)(I, std::get<I>(t));
23  loop<I + 1, Max>(t, std::forward<F>(f));
24  }
25  }
26 
31  template <typename ResultType, typename... ArgumentTypes>
32  struct RequestType {
33  public:
34  using Params = std::tuple<ArgumentTypes...>;
35  using Return = ResultType;
36 
37  private:
39 
40  public:
41  RequestType() = default;
42  virtual ~RequestType() = default;
43 
44  virtual outcome::result<ResultType> execute() = 0;
45 
46  RequestType(const RequestType &) = delete;
47  RequestType &operator=(const RequestType &) = delete;
48 
49  RequestType(RequestType &&) = delete;
50  RequestType &operator=(RequestType &&) = delete;
51 
52  outcome::result<void> init(const jsonrpc::Request::Parameters &params) {
53  if (params.size() <= sizeof...(ArgumentTypes)) {
54  loop<0, sizeof...(ArgumentTypes)>(params_,
55  [&](const auto ix, auto &dst) {
56  if (ix < params.size())
57  loadValue(dst, params[ix]);
58  });
59  return outcome::success();
60  }
61  throw jsonrpc::InvalidParametersFault("Incorrect number of params");
62  }
63 
64  template <size_t I>
65  auto getParam() ->
66  typename std::tuple_element<I, decltype(params_)>::type & {
67  static_assert(I < std::tuple_size<decltype(params_)>::value,
68  "Incorrect index.");
69  return std::get<I>(params_);
70  }
71 
72  private:
73  template <typename T>
74  void loadValue(std::optional<T> &dst, const jsonrpc::Value &src) {
75  if (!src.IsNil()) {
76  T t;
77  loadValue(t, src);
78  dst = std::move(t);
79  } else {
80  dst = std::nullopt;
81  }
82  }
83 
84  template <typename SequenceContainer,
85  typename = typename SequenceContainer::value_type,
86  typename = typename SequenceContainer::iterator>
87  void loadValue(SequenceContainer &dst, const jsonrpc::Value &src) {
88  if (!src.IsNil() && src.IsArray()) {
89  for (auto &v : src.AsArray()) {
90  typename SequenceContainer::value_type t;
91  loadValue(t, v);
92  dst.insert(dst.end(), std::move(t));
93  }
94  } else {
95  throw jsonrpc::InvalidParametersFault("invalid argument type");
96  }
97  }
98 
99  template <typename T>
100  std::enable_if_t<std::is_integral_v<T>, void> loadValue(
101  T &dst, const jsonrpc::Value &src) {
102  if (not src.IsInteger32() and not src.IsInteger64()) {
103  throw jsonrpc::InvalidParametersFault("invalid argument type");
104  }
105  auto num = src.AsInteger64();
106  if constexpr (std::is_signed_v<T>) {
107  if (num < std::numeric_limits<T>::min()
108  or num > std::numeric_limits<T>::max()) {
109  throw jsonrpc::InvalidParametersFault("invalid argument value");
110  }
111  } else {
112  if (num < 0
113  or static_cast<uint64_t>(num) > std::numeric_limits<T>::max()) {
114  throw jsonrpc::InvalidParametersFault("invalid argument value");
115  }
116  }
117  dst = num;
118  }
119 
120  void loadValue(bool &dst, const jsonrpc::Value &src) {
121  if (not src.IsBoolean()) {
122  throw jsonrpc::InvalidParametersFault("invalid argument type");
123  }
124  dst = src.AsBoolean();
125  }
126 
127  void loadValue(std::string &dst, const jsonrpc::Value &src) {
128  if (not src.IsString()) {
129  throw jsonrpc::InvalidParametersFault("invalid argument type");
130  }
131  dst = src.AsString();
132  }
133  };
134 
135 } // namespace kagome::api::details
136 
137 #endif // KAGOME_CHAIN_BASE_REQUEST_HPP
void loadValue(std::string &dst, const jsonrpc::Value &src)
RequestType & operator=(const RequestType &)=delete
std::enable_if_t< std::is_integral_v< T >, void > loadValue(T &dst, const jsonrpc::Value &src)
void loadValue(SequenceContainer &dst, const jsonrpc::Value &src)
void loadValue(bool &dst, const jsonrpc::Value &src)
void loadValue(std::optional< T > &dst, const jsonrpc::Value &src)
virtual outcome::result< ResultType > execute()=0
auto getParam() -> typename std::tuple_element< I, decltype(params_)>::type &
constexpr void loop(Tuple &t, F &&f)
outcome::result< void > init(const jsonrpc::Request::Parameters &params)