Skip to content

Commit 7e5a894

Browse files
committed
😉 wokrking serialization of tuples to json.
1 parent c3c6580 commit 7e5a894

File tree

4 files changed

+104
-2
lines changed

4 files changed

+104
-2
lines changed

pre/json/detail/dejsonizer.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,16 @@ namespace pre { namespace json { namespace detail {
181181

182182
auto t = boost::pfr::structure_tie(value);
183183
boost::hana::for_each(t,
184-
[this]<cx::static_string key_, class TVal>(pre::cx::key_value_pair<key_, TVal>& x) {
184+
[this](auto& x) {
185+
this->operator()(x);
186+
});
187+
}
188+
189+
//! tuples
190+
template<requirements::tuple_like T>
191+
void operator()(T& value) const {
192+
boost::hana::for_each(value,
193+
[this](auto& x) {
185194
this->operator()(x);
186195
});
187196
}

pre/json/detail/jsonizer.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,16 @@ namespace pre { namespace json { namespace detail {
137137
void operator()(const T& value) const {
138138
auto t = boost::pfr::structure_tie(value);
139139
boost::hana::for_each(t,
140-
[this]<cx::static_string key_, class TVal>(pre::cx::key_value_pair<key_, TVal> x) {
140+
[this](const auto& x) {
141+
this->operator()(x);
142+
});
143+
}
144+
145+
//! tuples
146+
template<requirements::tuple_like T>
147+
void operator()(const T& value) const {
148+
boost::hana::for_each(value,
149+
[this](const auto& x) {
141150
this->operator()(x);
142151
});
143152
}

pre/json/detail/sfinae_enabler.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,29 @@ namespace pre { namespace json { namespace detail {
6868
traits::is_associative_container<T>::value
6969
,T>::type;
7070

71+
namespace requirements {
72+
template<class T, std::size_t N>
73+
concept has_tuple_element =
74+
requires(T t) {
75+
typename std::tuple_element_t<N, std::remove_const_t<T>>;
76+
{ get<N>(t) } -> std::convertible_to<const std::tuple_element_t<N, T>&>;
77+
};
78+
79+
template<class T>
80+
concept tuple_like = !std::is_reference_v<T>
81+
&& requires(T t) {
82+
typename std::tuple_size<T>::type;
83+
requires std::derived_from<
84+
std::tuple_size<T>,
85+
std::integral_constant<std::size_t, std::tuple_size_v<T>>
86+
>;
87+
} && []<std::size_t... N>(std::index_sequence<N...>) {
88+
return (has_tuple_element<T, N> && ...);
89+
}(std::make_index_sequence<std::tuple_size_v<T>>());
90+
91+
template<class T>
92+
concept not_tuple_like = !tuple_like<T>;
93+
}
7194
}}}
7295

7396
#endif

test/dejsonize_test.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,5 +666,66 @@ BOOST_AUTO_TEST_CASE (compile_time_named_fields_no_adapt_struct) {
666666
BOOST_REQUIRE(vals == val_deserialized);
667667
}
668668

669+
{
670+
using pre::cx::key_value_pair;
671+
using namespace datamodel;
672+
using namespace std::literals;
673+
674+
auto val = std::make_tuple(
675+
key_value_pair<"ssh_public_key" , std::string> {"key"s},
676+
key_value_pair<"environment_name" , std::string> {"env"s},
677+
key_value_pair<"environment_zip_hash" , std::string> {"zip_hash"s},
678+
key_value_pair<"job_size" , std::size_t> {434343},
679+
key_value_pair<"environment_zip" , std::string> {"zip"s},
680+
key_value_pair<"user" , cashier> {{ .section="wine & spirits", .checkout_number=27}}
681+
);
682+
683+
auto val_json = pre::json::to_json(val);
684+
std::cout << val_json.dump(2) << std::endl;
685+
686+
auto val_deserialized = pre::json::from_json<decltype(val)>(val_json);
687+
688+
auto val_reserialized = pre::json::to_json(val_deserialized);
689+
std::cout << val_reserialized.dump(2) << std::endl;
690+
691+
BOOST_REQUIRE(val == val_deserialized);
692+
}
693+
694+
695+
{
696+
using pre::cx::key_value_pair;
697+
using namespace datamodel;
698+
using namespace std::literals;
699+
700+
auto val = std::make_tuple(
701+
key_value_pair<"ssh_public_key" , std::string> {"key"s},
702+
key_value_pair<"environment_name" , std::string> {"env"s},
703+
key_value_pair<"environment_zip_hash" , std::string> {"zip_hash"s},
704+
key_value_pair<"job_size" , std::size_t> {434343},
705+
key_value_pair<"environment_zip" , std::string> {"zip"s},
706+
key_value_pair<"user" , cashier> {{ .section="wine & spirits", .checkout_number=27}}
707+
);
708+
709+
std::vector vals { val };
710+
vals.push_back(std::make_tuple(
711+
key_value_pair<"ssh_public_key" , std::string> {"yoooo"s},
712+
key_value_pair<"environment_name" , std::string> {"woui"s},
713+
key_value_pair<"environment_zip_hash" , std::string> {"noooooo"s},
714+
key_value_pair<"job_size" , std::size_t> {540210},
715+
key_value_pair<"environment_zip" , std::string> {"timeeeee"s},
716+
key_value_pair<"user" , cashier> {{ .section="Gemüse", .checkout_number=3486}}
717+
));
718+
719+
auto val_json = pre::json::to_json(vals);
720+
std::cout << val_json.dump(2) << std::endl;
721+
722+
auto val_deserialized = pre::json::from_json<decltype(vals)>(val_json);
723+
724+
auto val_reserialized = pre::json::to_json(val_deserialized);
725+
std::cout << val_reserialized.dump(2) << std::endl;
726+
727+
BOOST_REQUIRE(vals == val_deserialized);
728+
}
729+
669730

670731
}

0 commit comments

Comments
 (0)