77#include " ../Result.hpp"
88#include " ../enums.hpp"
99#include " ../thirdparty/enchantum/enchantum.hpp"
10+ #include " ../internal/has_reflector.hpp"
1011#include " AreReaderAndWriter.hpp"
1112#include " Parent.hpp"
1213#include " Parser_base.hpp"
@@ -29,7 +30,20 @@ struct Parser<R, W, T, ProcessorsType> {
2930
3031 // / Expresses the variables as type T.
3132 static Result<T> read (const R& _r, const InputVarType& _var) noexcept {
32- if constexpr (ProcessorsType::underlying_enums_ ||
33+ if constexpr (internal::has_read_reflector<T>) {
34+ const auto wrap_in_t = [](auto && _named_tuple) -> Result<T> {
35+ try {
36+ using NT = decltype (_named_tuple);
37+ return Reflector<T>::to (std::forward<NT>(_named_tuple));
38+ } catch (std::exception& e) {
39+ return error (e.what ());
40+ }
41+ };
42+ return Parser<R, W, typename Reflector<T>::ReflType,
43+ ProcessorsType>::read (_r, _var)
44+ .and_then (wrap_in_t );
45+
46+ } else if constexpr (ProcessorsType::underlying_enums_ ||
3347 schemaful::IsSchemafulReader<R>) {
3448 static_assert (enchantum::ScopedEnum<T>,
3549 " The enum must be a scoped enum in order to retrieve "
@@ -44,7 +58,10 @@ struct Parser<R, W, T, ProcessorsType> {
4458
4559 template <class P >
4660 static void write (const W& _w, const T& _var, const P& _parent) {
47- if constexpr (ProcessorsType::underlying_enums_ ||
61+ if constexpr (internal::has_write_reflector<T>) {
62+ Parser<R, W, typename Reflector<T>::ReflType, ProcessorsType>::write (
63+ _w, Reflector<T>::from (_var), _parent);
64+ } else if constexpr (ProcessorsType::underlying_enums_ ||
4865 schemaful::IsSchemafulWriter<W>) {
4966 const auto val = static_cast <std::underlying_type_t <T>>(_var);
5067 ParentType::add_value (_w, val, _parent);
@@ -57,7 +74,12 @@ struct Parser<R, W, T, ProcessorsType> {
5774 static schema::Type to_schema (
5875 std::map<std::string, schema::Type>* _definitions) {
5976 using U = std::remove_cvref_t <T>;
60- return make_enum<U>(_definitions);
77+ if constexpr (internal::has_read_reflector<U> ||
78+ internal::has_write_reflector<U>) {
79+ return make_reference<U>(_definitions);
80+ } else {
81+ return make_enum<U>(_definitions);
82+ }
6183 }
6284
6385 private:
@@ -77,6 +99,19 @@ struct Parser<R, W, T, ProcessorsType> {
7799 ProcessorsType>::to_schema (_definitions);
78100 }
79101 }
102+
103+ template <class U >
104+ static schema::Type make_reference (
105+ std::map<std::string, schema::Type>* _definitions) {
106+ using Type = schema::Type;
107+ const auto name = make_type_name<U>();
108+
109+ if (_definitions->find (name) == _definitions->end ()) {
110+ (*_definitions)[name] = Parser<R, W, typename Reflector<U>::ReflType,
111+ ProcessorsType>::to_schema (_definitions);
112+ }
113+ return Type{Type::Reference{name}};
114+ }
80115};
81116
82117} // namespace rfl::parsing
0 commit comments