#pragma once #include "adminive/json.hpp" #include #include #include #include namespace adminive { inline constexpr std::string_view status_protocol = "adminive.status"; inline constexpr int status_protocol_version = 1; template struct Status_Value { using value_type = T; T value{}; std::string color; }; template Status_Value> status_value(T&& value, std::string color = {}) { return Status_Value>{std::forward(value), std::move(color)}; } template struct Is_Status_Value : std::false_type {}; template struct Is_Status_Value> : std::true_type {}; template concept Status_Value_Type = Is_Status_Value>::value; template struct Status_Inner_Value { using type = std::remove_cvref_t; }; template struct Status_Inner_Value> { using type = T; }; template using Status_Inner_Value_Type = typename Status_Inner_Value>::type; template Json encode_status_field(const T& value) { Json result = json_object(); if constexpr(Status_Value_Type) { json_set(result, "value", encode_json_value(value.value)); json_set(result, "color", value.color); } else { json_set(result, "value", encode_json_value(value)); } return result; } template Json to_status_descriptor_json() { const auto descriptor = describe(); Json fields = json_array(); std::apply([&](const auto&... item) { ([&] { using Field = std::remove_cvref_t; using Member = typename Field::member_type; using Value = Status_Inner_Value_Type; Json field = json_object(); json_set(field, "name", item.name()); json_set(field, "label", item.label()); json_set(field, "value_type", value_type_name()); json_set(field, "color", Status_Value_Type); if(!item.description().empty()) { json_set(field, "description", item.description()); } json_append(fields, std::move(field)); }(), ...); }, descriptor.fields()); Json result = json_object(); json_set(result, "protocol", status_protocol); json_set(result, "protocol_version", status_protocol_version); json_set(result, "name", descriptor.name()); json_set(result, "label", descriptor.label()); json_set(result, "value_type", "status_object"); json_set(result, "fields", std::move(fields)); return result; } template Json to_status_json(const T& value) { const auto descriptor = describe(); Json result = json_object(); std::apply([&](const auto&... item) { (json_set(result, item.name(), encode_status_field(item.get(value))), ...); }, descriptor.fields()); return result; } }