55 lines
1.6 KiB
C++
55 lines
1.6 KiB
C++
#pragma once
|
|
|
|
#include <adminive/adapters/boost_pfr.hpp>
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
namespace renderive::web {
|
|
template <class T>
|
|
struct Observer_Pfr_Adapter {
|
|
using Type = adminive::Boost_Pfr_Reflection_Adapter<T>;
|
|
};
|
|
|
|
namespace detail {
|
|
template <class T>
|
|
nlohmann::json observer_value_json(const T& value);
|
|
|
|
template <class T, class Adapter, std::size_t... Indices>
|
|
nlohmann::json observer_object_json(
|
|
const T& value, std::index_sequence<Indices...>) {
|
|
nlohmann::json result = nlohmann::json::object();
|
|
((result[std::string(Adapter::template name<Indices>())] =
|
|
observer_value_json(Adapter::template get<Indices>(value))),
|
|
...);
|
|
return result;
|
|
}
|
|
|
|
template <class T>
|
|
nlohmann::json observer_value_json(const T& value) {
|
|
using Value = std::remove_cvref_t<T>;
|
|
if constexpr (std::same_as<Value, std::string>) {
|
|
return value;
|
|
} else if constexpr (std::same_as<Value, bool> ||
|
|
std::is_arithmetic_v<Value>) {
|
|
return value;
|
|
} else if constexpr (std::is_enum_v<Value>) {
|
|
return static_cast<std::underlying_type_t<Value>>(value);
|
|
} else if constexpr (std::is_aggregate_v<Value>) {
|
|
using Adapter = typename Observer_Pfr_Adapter<Value>::Type;
|
|
return observer_object_json<Value, Adapter>(
|
|
value, std::make_index_sequence<Adapter::field_count>{});
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
} // namespace detail
|
|
|
|
template <class Observer>
|
|
nlohmann::json observer_json(const Observer& observer) {
|
|
return detail::observer_value_json(observer);
|
|
}
|
|
} // namespace renderive::web
|