123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #pragma once
- #include "library/cpp/json/writer/json_value.h"
- #include <limits>
- #include <util/generic/array_ref.h>
- #include <util/generic/deque.h>
- #include <util/generic/hash.h>
- #include <util/generic/list.h>
- #include <util/generic/map.h>
- #include <util/generic/maybe.h>
- namespace NJson {
- template<typename T>
- struct TConverter {
- };
- namespace {
- template<typename T>
- struct TDefaultEncoder {
- static inline TJsonValue Encode(T value) {
- return TJsonValue(value);
- }
- };
- template<typename T, typename E>
- struct TDefaultArrayEncoder {
- static TJsonValue Encode(const T& value) {
- TJsonValue result(NJson::JSON_ARRAY);
- auto& encodedArray = result.GetArraySafe();
- for (const auto& element : value) {
- encodedArray.push_back(TConverter<E>::Encode(element));
- }
- return result;
- }
- };
- template<typename T, typename E>
- struct TDefaultArrayDecoder {
- static T Decode(const TJsonValue& value) {
- T result;
- for (const auto& element : value.GetArraySafe()) {
- result.push_back(TConverter<E>::Decode(element));
- }
- return result;
- }
- };
- template<typename T, typename E>
- struct TDefaultArrayConverter: public TDefaultArrayEncoder<T, E>, public TDefaultArrayDecoder<T, E> {
- };
- template<typename T, typename E>
- struct TDefaultMapEncoder {
- static TJsonValue Encode(const T& value) {
- TJsonValue result(NJson::JSON_MAP);
- auto& encodedMap = result.GetMapSafe();
- for (const auto& [key, element] : value) {
- encodedMap[key] = TConverter<E>::Encode(element);
- }
- return result;
- }
- };
- template<typename T, typename E>
- struct TDefaultMapDecoder {
- static T Decode(const TJsonValue& value) {
- T result;
- for (const auto& [key, element] : value.GetMapSafe()) {
- result[key] = TConverter<E>::Decode(element);
- }
- return result;
- }
- };
- template<typename T, typename E>
- struct TDefaultMapConverter: public TDefaultMapEncoder<T, E>, public TDefaultMapDecoder<T, E> {
- };
- }
- template<>
- struct TConverter<TJsonValue> {
- static TJsonValue Encode(const TJsonValue& value) {
- return value;
- }
- static TJsonValue Decode(const TJsonValue& value) {
- return value;
- }
- };
- template<>
- struct TConverter<bool>: public TDefaultEncoder<bool> {
- static inline bool Decode(const TJsonValue& value) {
- return value.GetBooleanSafe();
- }
- };
- template<typename T>
- requires std::is_integral_v<T> && (!std::is_same_v<T, bool>)
- struct TConverter<T>: public TDefaultEncoder<T> {
- static T Decode(const TJsonValue& value) {
- if constexpr (std::is_signed_v<T>) {
- const auto decodedValue = value.GetIntegerSafe();
- if (decodedValue < std::numeric_limits<T>::min() || std::numeric_limits<T>::max() < decodedValue) {
- ythrow yexception() << "Out of range (got " << decodedValue << ")";
- }
- return static_cast<T>(decodedValue);
- } else {
- const auto decodedValue = value.GetUIntegerSafe();
- if (std::numeric_limits<T>::max() < decodedValue) {
- ythrow yexception() << "Out of range (got " << decodedValue << ")";
- }
- return static_cast<T>(decodedValue);
- }
- }
- };
- template<typename T>
- requires std::is_floating_point_v<T>
- struct TConverter<T>: public TDefaultEncoder<T> {
- static inline T Decode(const TJsonValue& value) {
- return static_cast<T>(value.GetDoubleSafe());
- }
- };
- template<>
- struct TConverter<TStringBuf>: public TDefaultEncoder<TStringBuf> {
- };
- template<>
- struct TConverter<TString>: public TDefaultEncoder<TString> {
- static inline TString Decode(const TJsonValue& value) {
- return value.GetStringSafe();
- }
- };
- template<typename T>
- struct TConverter<TMaybe<T>> {
- static TJsonValue Encode(const TMaybe<T>& value) {
- if (value.Defined()) {
- return TConverter<T>::Encode(*value);
- } else {
- return TJsonValue(NJson::JSON_NULL);
- }
- }
- static TMaybe<T> Decode(const TJsonValue& value) {
- if (value.IsDefined()) {
- return TConverter<T>::Decode(value);
- } else {
- return Nothing();
- }
- }
- };
- template<typename T>
- struct TConverter<TArrayRef<T>>: public TDefaultArrayEncoder<TArrayRef<T>, T> {
- };
- template<typename T>
- struct TConverter<TVector<T>>: public TDefaultArrayConverter<TVector<T>, T> {
- };
- template<typename T>
- struct TConverter<TList<T>>: public TDefaultArrayConverter<TList<T>, T> {
- };
- template<typename T>
- struct TConverter<TDeque<T>>: public TDefaultArrayConverter<TDeque<T>, T> {
- };
- template<typename T>
- struct TConverter<THashMap<TStringBuf, T>>: public TDefaultMapEncoder<THashMap<TStringBuf, T>, T> {
- };
- template<typename T>
- struct TConverter<THashMap<TString, T>>: public TDefaultMapConverter<THashMap<TString, T>, T> {
- };
- template<typename T>
- struct TConverter<TMap<TStringBuf, T>>: public TDefaultMapEncoder<TMap<TStringBuf, T>, T> {
- };
- template<typename T>
- struct TConverter<TMap<TString, T>>: public TDefaultMapConverter<TMap<TString, T>, T> {
- };
- }
|