Files
Renderive/web_server/app/common/Observer_Json.h
2026-08-17 15:24:28 +08:00

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