wip: add free function to_json/from_json support
This commit is contained in:
parent
0001032d42
commit
63241db76e
34
src/json.hpp
34
src/json.hpp
@ -143,6 +143,24 @@ struct has_json_traits
|
|||||||
static constexpr bool value = has_destructor<json_traits<T>>::value;
|
static constexpr bool value = has_destructor<json_traits<T>>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct to_json_fn
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto operator()(T&& val) const -> decltype(to_json(std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return to_json(std::forward<T>(val));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct from_json_fn
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto operator()(T&& val) const -> decltype(from_json(std::forward<T>(val)))
|
||||||
|
{
|
||||||
|
return from_json(std::forward<T>(val));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief helper class to create locales with decimal point
|
@brief helper class to create locales with decimal point
|
||||||
|
|
||||||
@ -165,6 +183,22 @@ struct DecimalSeparator : std::numpunct<char>
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// taken from ranges-v3
|
||||||
|
template <typename T>
|
||||||
|
struct __static_const
|
||||||
|
{
|
||||||
|
static constexpr T value{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T __static_const<T>::value;
|
||||||
|
|
||||||
|
inline namespace
|
||||||
|
{
|
||||||
|
constexpr auto const& to_json = __static_const<detail::to_json_fn>::value;
|
||||||
|
constexpr auto const& from_json = __static_const<detail::from_json_fn>::value;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief a class to store JSON values
|
@brief a class to store JSON values
|
||||||
|
|
||||||
|
|||||||
@ -42,22 +42,12 @@ struct pod_type {
|
|||||||
short c;
|
short c;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(pod_type const& lhs, pod_type const& rhs) noexcept
|
|
||||||
{
|
|
||||||
return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bit_more_complex_type {
|
struct bit_more_complex_type {
|
||||||
pod_type a;
|
pod_type a;
|
||||||
pod_type b;
|
pod_type b;
|
||||||
std::string c;
|
std::string c;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(bit_more_complex_type const &lhs,
|
|
||||||
bit_more_complex_type const &rhs) noexcept {
|
|
||||||
return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// best optional implementation ever
|
// best optional implementation ever
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class optional_type
|
class optional_type
|
||||||
@ -73,6 +63,43 @@ private:
|
|||||||
std::shared_ptr<T> _val;
|
std::shared_ptr<T> _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// free to/from_json functions
|
||||||
|
|
||||||
|
json to_json(empty_type)
|
||||||
|
{
|
||||||
|
return json::object();
|
||||||
|
}
|
||||||
|
|
||||||
|
json to_json(pod_type const& p)
|
||||||
|
{
|
||||||
|
return {{"a", p.a}, {"b", p.b}, {"c", p.c}};
|
||||||
|
}
|
||||||
|
|
||||||
|
json to_json(bit_more_complex_type const& p)
|
||||||
|
{
|
||||||
|
using nlohmann::to_json;
|
||||||
|
return json{{"a", to_json(p.a)}, {"b", to_json(p.b)}, {"c", p.c}};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
json to_json(optional_type<T> const& opt)
|
||||||
|
{
|
||||||
|
using nlohmann::to_json;
|
||||||
|
if (!opt)
|
||||||
|
return nullptr;
|
||||||
|
return to_json(*opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(pod_type const& lhs, pod_type const& rhs) noexcept
|
||||||
|
{
|
||||||
|
return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(bit_more_complex_type const &lhs,
|
||||||
|
bit_more_complex_type const &rhs) noexcept {
|
||||||
|
return std::tie(lhs.a, lhs.b, lhs.c) == std::tie(rhs.a, rhs.b, rhs.c);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool operator==(optional_type<T> const& lhs, optional_type<T> const& rhs)
|
inline bool operator==(optional_type<T> const& lhs, optional_type<T> const& rhs)
|
||||||
{
|
{
|
||||||
@ -163,7 +190,7 @@ TEST_CASE("constructors for user-defined types", "[udt]")
|
|||||||
{
|
{
|
||||||
SECTION("empty type")
|
SECTION("empty type")
|
||||||
{
|
{
|
||||||
udt::empty_type const e;
|
udt::empty_type const e{};
|
||||||
auto const j = json{e};
|
auto const j = json{e};
|
||||||
auto k = json::object();
|
auto k = json::object();
|
||||||
CHECK(j == k);
|
CHECK(j == k);
|
||||||
@ -300,3 +327,38 @@ TEST_CASE("get<> for user-defined types", "[udt]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("to_json free function", "[udt]")
|
||||||
|
{
|
||||||
|
SECTION("pod_type")
|
||||||
|
{
|
||||||
|
auto const e = udt::pod_type{42, 42, 42};
|
||||||
|
auto const expected = json{{"a", 42}, {"b", 42}, {"c", 42}};
|
||||||
|
|
||||||
|
auto const j = nlohmann::to_json(e);
|
||||||
|
CHECK(j == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("bit_more_complex_type")
|
||||||
|
{
|
||||||
|
auto const e =
|
||||||
|
udt::bit_more_complex_type{{42, 42, 42}, {41, 41, 41}, "forty"};
|
||||||
|
auto const expected = json{{"a", {{"a", 42}, {"b", 42}, {"c", 42}}},
|
||||||
|
{"b", {{"a", 41}, {"b", 41}, {"c", 41}}},
|
||||||
|
{"c", "forty"}};
|
||||||
|
auto const j = nlohmann::to_json(e);
|
||||||
|
CHECK(j == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("optional_type")
|
||||||
|
{
|
||||||
|
SECTION("from null")
|
||||||
|
{
|
||||||
|
udt::optional_type<udt::pod_type> o;
|
||||||
|
|
||||||
|
json expected;
|
||||||
|
auto const j = nlohmann::to_json(o);
|
||||||
|
CHECK(expected == j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user