forked from fabian-jung/tsmp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.cpp
73 lines (60 loc) · 1.61 KB
/
json.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <tsmp/introspect.hpp>
#include <concepts>
#include <range/v3/view/transform.hpp>
#include <type_traits>
template<class T>
concept Arithmetic = std::floating_point<T> || std::integral<T>;
std::string to_json(const auto& value);
std::string to_json(const char* const& cstr)
{
return fmt::format("\"{}\"", cstr);
}
std::string to_json(const std::string& str)
{
return fmt::format("\"{}\"", str);
}
std::string to_json(const Arithmetic auto& number)
{
return std::to_string(number);
}
template<std::ranges::input_range Range>
std::string to_json(const Range& range)
{
using value_type = typename Range::value_type;
using signature_t = std::string (*)(const value_type&);
const auto elements = ranges::transform_view(range, static_cast<signature_t>(to_json));
return fmt::format("[{}]", fmt::join(elements, ","));
}
std::string to_json(const auto& value)
{
tsmp::introspect introspect{value};
if constexpr (introspect.has_fields()) {
const auto fields = introspect.visit_fields([](size_t, std::string_view name, const auto& field) {
return fmt::format("\"{}\":{}", name, to_json(field));
});
return fmt::format("{{{}}}", fmt::join(fields, ","));
} else {
return "{}";
}
}
namespace json_example {
struct foo_t
{
int i{42};
float f{1337.0f};
const char* s = "Hello World!";
struct bar_t
{
int i{0};
} bar;
std::array<int, 4> numbers{1, 2, 3, 4};
};
}
int main(int, char*[])
{
json_example::foo_t foo;
fmt::print("{}\n", to_json(foo));
return 0;
}