scheme_cast.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #pragma once
  2. #include <util/generic/set.h>
  3. #include <util/generic/vector.h>
  4. #include <util/generic/map.h>
  5. #include <util/generic/hash.h>
  6. #include <util/generic/hash_set.h>
  7. #include <util/string/cast.h>
  8. #include <util/generic/yexception.h>
  9. #include "scheme.h"
  10. namespace NJsonConverters {
  11. class IJsonSerializable {
  12. public:
  13. virtual NSc::TValue ToTValue() const = 0;
  14. virtual void FromTValue(const NSc::TValue&, const bool validate) = 0;
  15. const TString ToJson(const bool sort = false) const {
  16. return ToTValue().ToJson(sort);
  17. }
  18. void FromJson(const TStringBuf& json, const bool validate = false) {
  19. NSc::TValue v = NSc::TValue::FromJson(json);
  20. FromTValue(v, validate);
  21. }
  22. virtual ~IJsonSerializable() = default;
  23. };
  24. //////////////////////////////////////////////////////////////////////
  25. // fwd declarations
  26. //////////////////////////////////////////////////////////////////////
  27. //TVector
  28. template <typename T, typename A>
  29. NSc::TValue ToTValue(const TVector<T, A>& x);
  30. template <typename T, typename A>
  31. void FromTValue(const NSc::TValue& x, TVector<T, A>& out, const bool validate);
  32. //THashMap
  33. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  34. NSc::TValue ToTValue(const THashMap<Key, T, HashFcn, EqualKey, Alloc>& x);
  35. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  36. void FromTValue(const NSc::TValue& x, THashMap<Key, T, HashFcn, EqualKey, Alloc>& out, const bool validate);
  37. //TMap
  38. template <class K, class V, class Less, class A>
  39. NSc::TValue ToTValue(const TMap<K, V, Less, A>& x);
  40. template <class K, class V, class Less, class A>
  41. void FromTValue(const NSc::TValue& x, TMap<K, V, Less, A>& out, const bool validate);
  42. //THashSet
  43. template <class V, class H, class E, class A>
  44. NSc::TValue ToTValue(const THashSet<V, H, E, A>& x);
  45. template <class V, class H, class E, class A>
  46. void FromTValue(const NSc::TValue& x, THashSet<V, H, E, A>& out, const bool validate);
  47. //TSet
  48. template <class K, class L, class A>
  49. NSc::TValue ToTValue(const TSet<K, L, A>& x);
  50. template <class K, class L, class A>
  51. void FromTValue(const NSc::TValue& x, TSet<K, L, A>& out, const bool validate);
  52. //std::pair
  53. template <class T1, class T2>
  54. NSc::TValue ToTValue(const std::pair<T1, T2>& x);
  55. template <class T1, class T2>
  56. void FromTValue(const NSc::TValue& x, std::pair<T1, T2>& out, const bool validate);
  57. //////////////////////////////////////////////////////////////////////
  58. // simple From, To helpers
  59. //////////////////////////////////////////////////////////////////////
  60. template <typename T, bool HasSerializer>
  61. struct TValueAndStrokaConv {};
  62. template <typename T>
  63. struct TValueAndStrokaConv<T, 0> {
  64. static NSc::TValue ToTValue(const T& x) {
  65. return NSc::TValue(x);
  66. }
  67. static void FromTValue(const NSc::TValue& x, T& out, const bool) {
  68. out = x;
  69. }
  70. static TString ToString(const T& x) {
  71. return ::ToString(x);
  72. }
  73. static void FromString(const TStringBuf& str, T& res, const bool) {
  74. res = ::FromString<T>(str);
  75. }
  76. };
  77. template <typename T>
  78. struct TValueAndStrokaConv<T, 1> {
  79. static NSc::TValue ToTValue(const T& x) {
  80. return x.ToTValue();
  81. }
  82. static void FromTValue(const NSc::TValue& x, T& out, const bool validate) {
  83. out.FromTValue(x, validate);
  84. }
  85. static TString ToString(const T& x) {
  86. return x.ToJson();
  87. }
  88. static void FromString(const TStringBuf& str, T& res, const bool validate) {
  89. res.FromJson(str, validate);
  90. }
  91. };
  92. template <typename T>
  93. NSc::TValue ToTValue(const T& x) {
  94. return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::ToTValue(x);
  95. }
  96. template <typename T>
  97. void FromTValue(const NSc::TValue& x, T& out, const bool validate) {
  98. return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::FromTValue(x, out, validate);
  99. }
  100. template <typename T>
  101. T FromTValue(const NSc::TValue& x, const bool validate) {
  102. T ret;
  103. FromTValue(x, ret, validate);
  104. return ret;
  105. }
  106. template <typename T>
  107. TString ToString(const T& x) {
  108. return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::ToString(x);
  109. }
  110. template <typename T>
  111. void FromString(const TStringBuf& str, T& res, const bool validate) {
  112. return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::FromString(str, res, validate);
  113. }
  114. template <typename T>
  115. T FromString(const TStringBuf& str, bool validate) {
  116. T ret;
  117. FromString(str, ret, validate);
  118. return ret;
  119. }
  120. namespace NPrivate {
  121. template <typename T>
  122. NSc::TValue ToTValueDict(const T& dict) {
  123. NSc::TValue out;
  124. out.SetDict();
  125. for (typename T::const_iterator it = dict.begin(); it != dict.end(); ++it) {
  126. out[ToString(it->first)] = NJsonConverters::ToTValue(it->second);
  127. }
  128. return out;
  129. }
  130. template <typename T>
  131. void FromTValueDict(const NSc::TValue& x, T& out, bool validate) {
  132. typedef typename T::key_type TKey;
  133. typedef typename T::mapped_type TMapped;
  134. if (validate)
  135. Y_ENSURE(x.IsDict() || x.IsNull(), "not valid input scheme");
  136. out.clear();
  137. if (x.IsDict()) {
  138. const NSc::TDict& dict = x.GetDict();
  139. for (const auto& it : dict) {
  140. TKey key = NJsonConverters::FromString<TKey>(it.first, validate);
  141. TMapped val = NJsonConverters::FromTValue<TMapped>(it.second, validate);
  142. out.insert(std::pair<TKey, TMapped>(key, val));
  143. }
  144. }
  145. }
  146. template <typename T>
  147. NSc::TValue ToTValueSet(const T& set) {
  148. NSc::TValue out;
  149. out.SetDict();
  150. for (typename T::const_iterator it = set.begin(); it != set.end(); ++it) {
  151. out[ToString(*it)] = NSc::Null();
  152. }
  153. return out;
  154. }
  155. template <typename T>
  156. void FromTValueSet(const NSc::TValue& x, T& out, const bool validate) {
  157. typedef typename T::key_type TKey;
  158. if (validate)
  159. Y_ENSURE(x.IsDict() || x.IsNull(), "not valid input scheme");
  160. out.clear();
  161. if (x.IsDict()) {
  162. const NSc::TDict& dict = x.GetDict();
  163. for (const auto& it : dict) {
  164. TKey key;
  165. NJsonConverters::FromString<TKey>(it.first, key, validate);
  166. out.insert(key);
  167. }
  168. }
  169. }
  170. }
  171. //////////////////////////////////////////////////////////////////////
  172. // TVector
  173. //////////////////////////////////////////////////////////////////////
  174. template <typename T, typename A>
  175. NSc::TValue ToTValue(const TVector<T, A>& x) {
  176. NSc::TValue out;
  177. out.SetArray();
  178. for (typename TVector<T, A>::const_iterator it = x.begin(); it != x.end(); ++it)
  179. out.Push(NJsonConverters::ToTValue(*it));
  180. return out;
  181. }
  182. template <typename T, typename A>
  183. void FromTValue(const NSc::TValue& x, TVector<T, A>& out, const bool validate) {
  184. if (validate)
  185. Y_ENSURE(x.IsArray() || x.IsNull(), "not valid input scheme");
  186. out.clear();
  187. if (x.IsArray()) {
  188. const NSc::TArray& arr = x.GetArray();
  189. out.reserve(arr.size());
  190. for (const auto& it : arr) {
  191. T val;
  192. NJsonConverters::FromTValue(it, val, validate);
  193. out.push_back(val);
  194. }
  195. }
  196. }
  197. //////////////////////////////////////////////////////////////////////
  198. // THashMap & TMap
  199. //////////////////////////////////////////////////////////////////////
  200. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  201. NSc::TValue ToTValue(const THashMap<Key, T, HashFcn, EqualKey, Alloc>& x) {
  202. return NPrivate::ToTValueDict(x);
  203. }
  204. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  205. void FromTValue(const NSc::TValue& x, THashMap<Key, T, HashFcn, EqualKey, Alloc>& out, const bool validate) {
  206. NPrivate::FromTValueDict(x, out, validate);
  207. }
  208. template <class K, class V, class Less, class A>
  209. NSc::TValue ToTValue(const TMap<K, V, Less, A>& x) {
  210. return NPrivate::ToTValueDict(x);
  211. }
  212. template <class K, class V, class Less, class A>
  213. void FromTValue(const NSc::TValue& x, TMap<K, V, Less, A>& out, const bool validate) {
  214. NPrivate::FromTValueDict(x, out, validate);
  215. }
  216. //////////////////////////////////////////////////////////////////////
  217. // THashSet & TSet
  218. //////////////////////////////////////////////////////////////////////
  219. template <class V, class H, class E, class A>
  220. NSc::TValue ToTValue(const THashSet<V, H, E, A>& x) {
  221. return NPrivate::ToTValueSet(x);
  222. }
  223. template <class V, class H, class E, class A>
  224. void FromTValue(const NSc::TValue& x, THashSet<V, H, E, A>& out, const bool validate) {
  225. NPrivate::FromTValueSet(x, out, validate);
  226. }
  227. template <class K, class L, class A>
  228. NSc::TValue ToTValue(const TSet<K, L, A>& x) {
  229. return NPrivate::ToTValueSet(x);
  230. }
  231. template <class K, class L, class A>
  232. void FromTValue(const NSc::TValue& x, TSet<K, L, A>& out, const bool validate) {
  233. NPrivate::FromTValueSet(x, out, validate);
  234. }
  235. //////////////////////////////////////////////////////////////////////
  236. // std::pair
  237. //////////////////////////////////////////////////////////////////////
  238. template <class T1, class T2>
  239. NSc::TValue ToTValue(const std::pair<T1, T2>& x) {
  240. NSc::TValue out;
  241. out.SetArray();
  242. out.Push(NJsonConverters::ToTValue(x.first));
  243. out.Push(NJsonConverters::ToTValue(x.second));
  244. return out;
  245. }
  246. template <class T1, class T2>
  247. void FromTValue(const NSc::TValue& x, std::pair<T1, T2>& out, const bool validate) {
  248. if (validate)
  249. Y_ENSURE(x.IsArray() || x.IsNull(), "not valid input scheme");
  250. if (x.IsArray()) {
  251. const NSc::TArray& arr = x.GetArray();
  252. if (arr.size() == 2) {
  253. T1 val0;
  254. T2 val1;
  255. NJsonConverters::FromTValue(arr[0], val0, validate);
  256. NJsonConverters::FromTValue(arr[1], val1, validate);
  257. out.first = val0;
  258. out.second = val1;
  259. }
  260. }
  261. }
  262. //////////////////////////////////////////////////////////////////////
  263. // global user functions
  264. //////////////////////////////////////////////////////////////////////
  265. template <typename T>
  266. TString ToJson(const T& val, const bool sort = false) {
  267. return NJsonConverters::ToTValue(val).ToJson(sort);
  268. }
  269. template <typename T>
  270. T FromJson(const TStringBuf& json, bool validate = false) {
  271. NSc::TValue v = NSc::TValue::FromJson(json);
  272. T ret;
  273. NJsonConverters::FromTValue(v, ret, validate);
  274. return ret;
  275. }
  276. }