File: IsReader.hpp

package info (click to toggle)
reflect-cpp 0.21.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,128 kB
  • sloc: cpp: 50,336; python: 139; makefile: 30; sh: 3
file content (92 lines) | stat: -rw-r--r-- 3,202 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef RFL_PARSING_ISREADER_HPP_
#define RFL_PARSING_ISREADER_HPP_

#include <array>
#include <concepts>
#include <cstdint>
#include <functional>
#include <optional>
#include <string>
#include <string_view>

#include "../Result.hpp"
#include "../internal/is_basic_type.hpp"
#include "../internal/wrap_in_rfl_array_t.hpp"
#include "SupportsTaggedUnions.hpp"
#include "schemaful/IsSchemafulReader.hpp"

namespace rfl {
namespace parsing {

template <class R>
struct MockArrayReader {
  std::optional<Error> read(typename R::InputVarType&) const {
    return std::nullopt;
  }
};

template <class R>
struct MockObjectReader {
  void read(const std::string_view&, typename R::InputVarType&) const {}
};

template <class R, class T>
concept IsReader =
    (SupportsTaggedUnions<R> || schemaful::IsSchemafulReader<R>) &&
    requires(R r, std::string name,
             std::function<std::int16_t(std::string_view)> fct,
             MockArrayReader<R> array_reader, MockObjectReader<R> object_reader,
             typename R::InputArrayType arr, typename R::InputObjectType obj,
             typename R::InputVarType var, size_t idx) {
      /// Any Reader needs to define the following:
      ///
      /// 1) An InputArrayType, which must be an array-like data structure.
      /// 2) An InputObjectType, which must contain key-value pairs.
      /// 3) An InputVarType, which must be able to represent either
      ///    InputArrayType, InputObjectType or a basic type (bool, integral,
      ///    floating point, std::string).
      /// 4) A static constexpr bool has_custom_constructor, that determines
      ///    whether the class in question as a custom constructor, which might
      ///    be called something like from_json_obj(...).

      /// Determines whether a variable is empty (the NULL type).
      { r.is_empty(var) } -> std::same_as<bool>;

      /// Iterates through an array and writes the contained vars into
      /// an array reader.
      { r.read_array(array_reader, arr) } -> std::same_as<std::optional<Error>>;

      /// Iterates through an object and writes the key-value pairs into an
      /// object reader. This is what we use to handle structs and named tuples,
      /// making it a very important function.
      {
        r.read_object(object_reader, obj)
      } -> std::same_as<std::optional<Error>>;

      /// Transforms var to a basic type (bool, integral,
      /// floating point, std::string)
      {
        r.template to_basic_type<internal::wrap_in_rfl_array_t<T>>(var)
      } -> std::same_as<rfl::Result<internal::wrap_in_rfl_array_t<T>>>;

      /// Casts var as an InputArrayType.
      {
        r.to_array(var)
      } -> std::same_as<rfl::Result<typename R::InputArrayType>>;

      /// Casts var as an InputObjectType.
      {
        r.to_object(var)
      } -> std::same_as<rfl::Result<typename R::InputObjectType>>;

      /// Uses the custom constructor, if it has been determined that T has one
      /// (see above).
      {
        r.template use_custom_constructor<internal::wrap_in_rfl_array_t<T>>(var)
      } -> std::same_as<rfl::Result<internal::wrap_in_rfl_array_t<T>>>;
    };

}  // namespace parsing
}  // namespace rfl

#endif