6#include <userver/formats/json/value.hpp>
7#include <userver/formats/parse/to.hpp>
8#include <userver/formats/serialize/to.hpp>
9#include <userver/utils/constexpr_indices.hpp>
10#include <userver/utils/overloaded.hpp>
11#include <userver/utils/trivial_map.hpp>
13USERVER_NAMESPACE_BEGIN
17template <
typename BuilderFunc>
19 std::string_view property_name;
20 utils::TrivialSet<BuilderFunc> mapping;
23template <
typename BuilderFunc>
24OneOfSettings(
const char*, utils::TrivialSet<BuilderFunc>)
27template <
const auto* Settings,
typename... T>
29 const std::variant<formats::common::ParseType<formats::json::Value, T>...>&
33template <
const auto* Settings,
typename... T,
typename Value>
34std::variant<formats::common::ParseType<Value, T>...> Parse(
35 Value value, formats::parse::To<OneOfWithDiscriminator<Settings, T...>>) {
36 const auto field = value[Settings->property_name].
template As<std::string>();
38 const auto index = Settings->mapping.GetIndex(field);
39 if (!index.has_value()) {
44 std::variant<formats::common::ParseType<formats::json::Value, T>...>;
47 utils::WithConstexprIndex<
sizeof...(T)>(
48 index.value(), [&](
auto index_constant) {
49 constexpr auto kIndex =
decltype(index_constant)::value;
50 result.
template emplace<kIndex>(
51 value.
template As<std::variant_alternative_t<kIndex, Result>>());
56template <
const auto* Settings,
typename... T,
typename Value>
57Value Serialize(
const OneOfWithDiscriminator<Settings, T...>& var,
60 USERVER_NAMESPACE::utils::Overloaded{
61 [](
const formats::common::ParseType<Value, T>& item) {
62 return typename Value::Builder(T{item}).ExtractValue();