@@ -48,7 +48,69 @@ class Parser<R, W, std::variant<AlternativeTypes...>, ProcessorsType> {
4848 static Result<std::variant<AlternativeTypes...>> read (
4949 const R& _r, const InputVarType& _var) noexcept {
5050 if constexpr (internal::all_fields<std::tuple<AlternativeTypes...>>()) {
51- --snip--
51+ if constexpr (schemaful::IsSchemafulReader<R>) {
52+ using WrappedType = rfl::Variant<NamedTuple<AlternativeTypes>...>;
53+ return Parser<R, W, WrappedType, ProcessorsType>::read (_r, _var)
54+ .transform (
55+ [](auto && _variant) -> std::variant<AlternativeTypes...> {
56+ return std::move (_variant).visit ([](auto && _named_tuple) {
57+ return std::variant<AlternativeTypes...>(std::move (
58+ std::move (_named_tuple).fields ().template get <0 >()));
59+ });
60+ });
61+
62+ } else {
63+ const auto wrap = [](auto && _v) {
64+ return std::variant<AlternativeTypes...>(std::move (_v));
65+ };
66+ const auto to_std_variant = [&](auto && _v) {
67+ return rfl::visit (wrap, std::move (_v));
68+ };
69+ return FieldVariantParser<R, W, ProcessorsType,
70+ AlternativeTypes...>::read (_r, _var)
71+ .transform (to_std_variant);
72+ }
73+
74+ } else if constexpr (schemaful::IsSchemafulReader<R>) {
75+ using V =
76+ schemaful::VariantReader<R, W, std::variant<AlternativeTypes...>,
77+ ProcessorsType, AlternativeTypes...>;
78+ return _r.to_union (_var).and_then ([&](const auto & _u) {
79+ return _r.template read_union <std::variant<AlternativeTypes...>, V>(_u);
80+ });
81+
82+ } else if constexpr (internal::add_tags_to_variants_v<ProcessorsType> ||
83+ internal::add_namespaced_tags_to_variants_v<
84+ ProcessorsType>) {
85+ constexpr bool remove_namespaces =
86+ internal::add_tags_to_variants_v<ProcessorsType>;
87+ using FieldVariantType = rfl::Variant<
88+ VariantAlternativeWrapper<AlternativeTypes, remove_namespaces>...>;
89+ const auto from_field_variant =
90+ [](auto && _field) -> std::variant<AlternativeTypes...> {
91+ return std::move (_field.value ());
92+ };
93+ return Parser<R, W, FieldVariantType, ProcessorsType>::read (_r, _var)
94+ .transform ([&](FieldVariantType&& _f) {
95+ return _f.visit (from_field_variant);
96+ });
97+
98+ } else {
99+ std::optional<std::variant<AlternativeTypes...>> result;
100+ std::vector<std::string> errors;
101+ errors.reserve (sizeof ...(AlternativeTypes));
102+ read_variant (
103+ _r, _var, &result, &errors,
104+ std::make_integer_sequence<int , sizeof ...(AlternativeTypes)>());
105+ if (result) {
106+ return std::move (*result);
107+ } else {
108+ return error (
109+ to_single_error_message (errors,
110+ " Could not parse the variant. Each of the "
111+ " possible alternatives failed "
112+ " for the following reasons: " ,
113+ 100000 ));
52114 }
53115 }
54116 }
@@ -66,7 +128,67 @@ class Parser<R, W, std::variant<AlternativeTypes...>, ProcessorsType> {
66128 const std::variant<AlternativeTypes...>& _variant,
67129 const P& _parent) {
68130 if constexpr (internal::all_fields<std::tuple<AlternativeTypes...>>()) {
69- --snip--
131+ if constexpr (schemaful::IsSchemafulWriter<W>) {
132+ using WrappedType = rfl::Variant<
133+ NamedTuple<Field<AlternativeTypes::name_,
134+ const typename AlternativeTypes::Type*>>...>;
135+ const auto to_wrapped = [](const auto & _variant) -> WrappedType {
136+ return std::visit (
137+ [](const auto & _field) -> WrappedType {
138+ return make_named_tuple (internal::to_ptr_field (_field));
139+ },
140+ _variant);
141+ };
142+ Parser<R, W, WrappedType, ProcessorsType>::write (
143+ _w, to_wrapped (_variant), _parent);
144+
145+ } else {
146+ const auto wrap = [](const auto & _v) {
147+ return rfl::Variant<ptr_field_t <AlternativeTypes>...>(
148+ internal::to_ptr_field (_v));
149+ };
150+ const auto to_rfl_variant = [&](const auto & _v) {
151+ return std::visit (wrap, _v);
152+ };
153+ FieldVariantParser<
154+ R, W, ProcessorsType,
155+ ptr_field_t <AlternativeTypes>...>::write (_w,
156+ to_rfl_variant (_variant),
157+ _parent);
158+ }
159+
160+ } else if constexpr (schemaful::IsSchemafulWriter<W>) {
161+ return std::visit (
162+ [&](const auto & _v) {
163+ using Type = std::remove_cvref_t <decltype (_v)>;
164+ auto u = ParentType::add_union (_w, _parent);
165+ using UnionType = typename ParentType::template Union<decltype (u)>;
166+ auto p = UnionType{.index_ = static_cast <size_t >(_variant.index ()),
167+ .union_ = &u};
168+ Parser<R, W, Type, ProcessorsType>::write (_w, _v, p);
169+ },
170+ _variant);
171+
172+ } else if constexpr (internal::add_tags_to_variants_v<ProcessorsType> ||
173+ internal::add_namespaced_tags_to_variants_v<
174+ ProcessorsType>) {
175+ constexpr bool remove_namespaces =
176+ internal::add_tags_to_variants_v<ProcessorsType>;
177+ using FieldVariantType =
178+ rfl::Variant<VariantAlternativeWrapper<const AlternativeTypes*,
179+ remove_namespaces>...>;
180+ const auto to_field_variant =
181+ []<class T >(const T& _t) -> FieldVariantType {
182+ return VariantAlternativeWrapper<const T*, remove_namespaces>(&_t);
183+ };
184+ Parser<R, W, FieldVariantType, ProcessorsType>::write (
185+ _w, std::visit (to_field_variant, _variant), _parent);
186+
187+ } else {
188+ const auto handle = [&](const auto & _v) {
189+ using Type = std::remove_cvref_t <decltype (_v)>;
190+ Parser<R, W, Type, ProcessorsType>::write (_w, _v, _parent);
191+ };
70192 return std::visit (handle, _variant);
71193 }
72194 }
@@ -80,7 +202,25 @@ class Parser<R, W, std::variant<AlternativeTypes...>, ProcessorsType> {
80202 static schema::Type to_schema (
81203 std::map<std::string, schema::Type>* _definitions) {
82204 if constexpr (internal::all_fields<std::tuple<AlternativeTypes...>>()) {
83- --snip--
205+ return FieldVariantParser<R, W, ProcessorsType,
206+ AlternativeTypes...>::to_schema (_definitions);
207+
208+ } else if constexpr (internal::add_tags_to_variants_v<ProcessorsType> ||
209+ internal::add_namespaced_tags_to_variants_v<
210+ ProcessorsType>) {
211+ constexpr bool remove_namespaces =
212+ internal::add_tags_to_variants_v<ProcessorsType>;
213+ using FieldVariantType = rfl::Variant<
214+ VariantAlternativeWrapper<AlternativeTypes, remove_namespaces>...>;
215+ return Parser<R, W, FieldVariantType, ProcessorsType>::to_schema (
216+ _definitions);
217+
218+ } else {
219+ std::vector<schema::Type> types;
220+ build_schema (
221+ _definitions, &types,
222+ std::make_integer_sequence<int , sizeof ...(AlternativeTypes)>());
223+ return schema::Type{schema::Type::AnyOf{.types_ = std::move (types)}};
84224 }
85225 }
86226
@@ -158,7 +298,6 @@ class Parser<R, W, std::variant<AlternativeTypes...>, ProcessorsType> {
158298 (read_one_alternative<_is>(_r, _var, _result, _errors), ...);
159299 }
160300};
161- };
162301
163302} // namespace rfl::parsing
164303
0 commit comments