converter.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #pragma once
  2. #include "library/cpp/json/writer/json_value.h"
  3. #include <limits>
  4. #include <util/generic/array_ref.h>
  5. #include <util/generic/deque.h>
  6. #include <util/generic/hash.h>
  7. #include <util/generic/list.h>
  8. #include <util/generic/map.h>
  9. #include <util/generic/maybe.h>
  10. namespace NJson {
  11. template<typename T>
  12. struct TConverter {
  13. };
  14. namespace {
  15. template<typename T>
  16. struct TDefaultEncoder {
  17. static inline TJsonValue Encode(T value) {
  18. return TJsonValue(value);
  19. }
  20. };
  21. template<typename T, typename E>
  22. struct TDefaultArrayEncoder {
  23. static TJsonValue Encode(const T& value) {
  24. TJsonValue result(NJson::JSON_ARRAY);
  25. auto& encodedArray = result.GetArraySafe();
  26. for (const auto& element : value) {
  27. encodedArray.push_back(TConverter<E>::Encode(element));
  28. }
  29. return result;
  30. }
  31. };
  32. template<typename T, typename E>
  33. struct TDefaultArrayDecoder {
  34. static T Decode(const TJsonValue& value) {
  35. T result;
  36. for (const auto& element : value.GetArraySafe()) {
  37. result.push_back(TConverter<E>::Decode(element));
  38. }
  39. return result;
  40. }
  41. };
  42. template<typename T, typename E>
  43. struct TDefaultArrayConverter: public TDefaultArrayEncoder<T, E>, public TDefaultArrayDecoder<T, E> {
  44. };
  45. template<typename T, typename E>
  46. struct TDefaultMapEncoder {
  47. static TJsonValue Encode(const T& value) {
  48. TJsonValue result(NJson::JSON_MAP);
  49. auto& encodedMap = result.GetMapSafe();
  50. for (const auto& [key, element] : value) {
  51. encodedMap[key] = TConverter<E>::Encode(element);
  52. }
  53. return result;
  54. }
  55. };
  56. template<typename T, typename E>
  57. struct TDefaultMapDecoder {
  58. static T Decode(const TJsonValue& value) {
  59. T result;
  60. for (const auto& [key, element] : value.GetMapSafe()) {
  61. result[key] = TConverter<E>::Decode(element);
  62. }
  63. return result;
  64. }
  65. };
  66. template<typename T, typename E>
  67. struct TDefaultMapConverter: public TDefaultMapEncoder<T, E>, public TDefaultMapDecoder<T, E> {
  68. };
  69. }
  70. template<>
  71. struct TConverter<TJsonValue> {
  72. static TJsonValue Encode(const TJsonValue& value) {
  73. return value;
  74. }
  75. static TJsonValue Decode(const TJsonValue& value) {
  76. return value;
  77. }
  78. };
  79. template<>
  80. struct TConverter<bool>: public TDefaultEncoder<bool> {
  81. static inline bool Decode(const TJsonValue& value) {
  82. return value.GetBooleanSafe();
  83. }
  84. };
  85. template<typename T>
  86. requires std::is_integral_v<T> && (!std::is_same_v<T, bool>)
  87. struct TConverter<T>: public TDefaultEncoder<T> {
  88. static T Decode(const TJsonValue& value) {
  89. if constexpr (std::is_signed_v<T>) {
  90. const auto decodedValue = value.GetIntegerSafe();
  91. if (decodedValue < std::numeric_limits<T>::min() || std::numeric_limits<T>::max() < decodedValue) {
  92. ythrow yexception() << "Out of range (got " << decodedValue << ")";
  93. }
  94. return static_cast<T>(decodedValue);
  95. } else {
  96. const auto decodedValue = value.GetUIntegerSafe();
  97. if (std::numeric_limits<T>::max() < decodedValue) {
  98. ythrow yexception() << "Out of range (got " << decodedValue << ")";
  99. }
  100. return static_cast<T>(decodedValue);
  101. }
  102. }
  103. };
  104. template<typename T>
  105. requires std::is_floating_point_v<T>
  106. struct TConverter<T>: public TDefaultEncoder<T> {
  107. static inline T Decode(const TJsonValue& value) {
  108. return static_cast<T>(value.GetDoubleSafe());
  109. }
  110. };
  111. template<>
  112. struct TConverter<TStringBuf>: public TDefaultEncoder<TStringBuf> {
  113. };
  114. template<>
  115. struct TConverter<TString>: public TDefaultEncoder<TString> {
  116. static inline TString Decode(const TJsonValue& value) {
  117. return value.GetStringSafe();
  118. }
  119. };
  120. template<typename T>
  121. struct TConverter<TMaybe<T>> {
  122. static TJsonValue Encode(const TMaybe<T>& value) {
  123. if (value.Defined()) {
  124. return TConverter<T>::Encode(*value);
  125. } else {
  126. return TJsonValue(NJson::JSON_NULL);
  127. }
  128. }
  129. static TMaybe<T> Decode(const TJsonValue& value) {
  130. if (value.IsDefined()) {
  131. return TConverter<T>::Decode(value);
  132. } else {
  133. return Nothing();
  134. }
  135. }
  136. };
  137. template<typename T>
  138. struct TConverter<TArrayRef<T>>: public TDefaultArrayEncoder<TArrayRef<T>, T> {
  139. };
  140. template<typename T>
  141. struct TConverter<TVector<T>>: public TDefaultArrayConverter<TVector<T>, T> {
  142. };
  143. template<typename T>
  144. struct TConverter<TList<T>>: public TDefaultArrayConverter<TList<T>, T> {
  145. };
  146. template<typename T>
  147. struct TConverter<TDeque<T>>: public TDefaultArrayConverter<TDeque<T>, T> {
  148. };
  149. template<typename T>
  150. struct TConverter<THashMap<TStringBuf, T>>: public TDefaultMapEncoder<THashMap<TStringBuf, T>, T> {
  151. };
  152. template<typename T>
  153. struct TConverter<THashMap<TString, T>>: public TDefaultMapConverter<THashMap<TString, T>, T> {
  154. };
  155. template<typename T>
  156. struct TConverter<TMap<TStringBuf, T>>: public TDefaultMapEncoder<TMap<TStringBuf, T>, T> {
  157. };
  158. template<typename T>
  159. struct TConverter<TMap<TString, T>>: public TDefaultMapConverter<TMap<TString, T>, T> {
  160. };
  161. }