#ifndef RFL_PARSING_ISREADER_HPP_ #define RFL_PARSING_ISREADER_HPP_ #include #include #include #include #include #include #include #include "../Result.hpp" #include "../internal/is_basic_type.hpp" #include "../internal/wrap_in_rfl_array_t.hpp" namespace rfl { namespace parsing { template struct MockArrayReader { std::optional read(typename R::InputVarType& _var) const { return std::nullopt; } }; template struct MockObjectReader { void read(const std::string_view& _name, typename R::InputVarType& _var) const {} }; template concept IsReader = requires(R r, std::string name, std::function fct, MockArrayReader array_reader, MockObjectReader object_reader, typename R::InputArrayType arr, typename R::InputObjectType obj, typename R::InputVarType var) { /// 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(...). /// Retrieves a particular field from an object. { r.get_field(name, obj) } -> std::same_as>; /// Determines whether a variable is empty (the NULL type). { r.is_empty(var) } -> std::same_as; /// Iterates through an array and writes the contained vars into /// an array reader. { r.read_array(array_reader, arr) } -> std::same_as>; /// 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>; /// Transforms var to a basic type (bool, integral, /// floating point, std::string) { r.template to_basic_type>(var) } -> std::same_as>>; /// Casts var as an InputArrayType. { r.to_array(var) } -> std::same_as>; /// Casts var as an InputObjectType. { r.to_object(var) } -> std::same_as>; /// Uses the custom constructor, if it has been determined that T has one /// (see above). { r.template use_custom_constructor>(var) } -> std::same_as>>; }; } // namespace parsing } // namespace rfl #endif