converter.h 5.6 KB

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