virthttp  0.0
libvirt http interface
actions_table.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <array>
4 #include <functional>
5 #include <string_view>
6 #include <gsl/gsl>
7 #include "cexpr_algs.hpp"
8 #include "depends.hpp"
9 #include "json2virt.hpp"
10 #include "json_utils.hpp"
11 #include "utils.hpp"
12 
13 #define PM_LIFT(mem_fn) [&](auto... args) { return mem_fn(args...); }
14 #define PM_PREREQ(...) [&] { __VA_ARGS__ return DependsOutcome::SUCCESS; }
15 
16 using namespace std::literals;
17 
18 template <typename Flag>
19 constexpr const auto getFlag = [](const rapidjson::Value& json_flag, auto error) {
20  if (auto v = Flag::from_string({json_flag.GetString(), json_flag.GetStringLength()}); v)
21  return std::optional{*v};
22  return error(301), std::optional<Flag>{std::nullopt};
23 };
24 template <class F> auto getCombinedFlags(const rapidjson::Value& json_flag, JsonRes& json_res) noexcept -> std::optional<F> {
25  auto error = [&](auto... args) { return json_res.error(args...), std::nullopt; };
26 
27  F flagset{};
28  if (json_flag.IsArray()) {
29  const auto json_arr = json_flag.GetArray();
30  if constexpr (test_sfinae([](auto f) -> decltype(f | f) { UNREACHABLE; }, F{})) {
31  for (const auto& json_str : json_arr) {
32  const auto v = getFlag<F>(json_str, error);
33  if (!v)
34  return std::nullopt;
35  flagset |= *v;
36  }
37  } else {
38  if (json_arr.Size() > 1)
39  return error(301);
40  return {json_arr.Empty() ? F{} : getFlag<F>(json_arr[0], error)};
41  }
42  } else if (json_flag.IsString()) {
43  const auto v = getFlag<F>(json_flag, error);
44  if (!v)
45  return std::nullopt;
46  flagset = *v;
47  }
48  return {flagset};
49 }
50 
51 constexpr auto action_scope = [](auto&&... actions) {
52  using Arr = std::array<std::function<DependsOutcome()>, sizeof...(actions)>; // pray for SFO ; wait for expansion statements
53  for (auto&& action : Arr{actions...}) {
54  if (const auto ao = action(); ao != DependsOutcome::SKIPPED)
55  return ao;
56  }
58 };
59 
60 template <class CRTP, class Hdl> class NamedCallTable {
61  [[nodiscard]] constexpr auto keys() const noexcept -> auto& { return static_cast<const CRTP&>(*this).keys; }
62  [[nodiscard]] constexpr auto fcns() const noexcept -> auto& { return static_cast<const CRTP&>(*this).fcns; }
63 
64  public:
65  constexpr Hdl operator[](std::string_view sv) const noexcept {
66  const auto it = cexpr::find(keys().begin(), keys().end(), sv);
67  if (it == keys().end())
68  return nullptr;
69  const auto idx = std::distance(keys().begin(), it);
70  return fcns()[idx];
71  }
72 };
#define UNREACHABLE
Definition: utility.hpp:19
constexpr Hdl operator[](std::string_view sv) const noexcept
Definition: actions_table.hpp:65
auto getCombinedFlags(const rapidjson::Value &json_flag, JsonRes &json_res) noexcept-> std::optional< F >
Definition: actions_table.hpp:24
Definition: json_utils.hpp:21
constexpr auto action_scope
Definition: actions_table.hpp:51
constexpr auto test_sfinae(Lambda lambda, Ts &&...) -> decltype(lambda(std::declval< Ts >()...), bool
Definition: utility.hpp:37
constexpr InputIt find(InputIt first, InputIt last, const T &value)
Definition: cexpr_algs.hpp:4
constexpr const auto getFlag
Definition: actions_table.hpp:19
Definition: actions_table.hpp:60