Skip to content

Commit 08fdf6f

Browse files
Minor bugfixes
1 parent 3351515 commit 08fdf6f

3 files changed

Lines changed: 146 additions & 11 deletions

File tree

include/rfl/parsing/Parser_variant.hpp

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

include/rfl/yas/Reader.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ struct Reader {
4242

4343
/// @brief Indicates whether a custom constructor exists for type T.
4444
/// @tparam T The type to check for a custom constructor.
45-
static constexpr bool has_custom_constructor = false;
45+
template <class T>
46+
static constexpr bool has_custom_constructor =
47+
(requires(InputVarType var) { T::from_yas_obj(var); });
4648

4749
/// @brief Checks if the given input variable is empty.
4850
/// @param _var The input variable to check.

include/rfl/yas/Writer.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,6 @@ struct Writer {
4848
/// @param _ar Pointer to the output archive used for serialization.
4949
Writer(OArchive* _ar) : ar_(_ar) {}
5050

51-
///
52-
/// @brief Indicates whether a custom constructor exists for type T.
53-
/// @tparam T The type to check for a custom constructor.
54-
template <class T>
55-
static constexpr bool has_custom_constructor = false;
56-
5751
///
5852
/// @brief Begins serializing an array as the root object.
5953
/// @param _size The number of elements in the array.

0 commit comments

Comments
 (0)