123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- #pragma once
- #include <util/generic/set.h>
- #include <util/generic/vector.h>
- #include <util/generic/map.h>
- #include <util/generic/hash.h>
- #include <util/generic/hash_set.h>
- #include <util/string/cast.h>
- #include <util/generic/yexception.h>
- #include "scheme.h"
- namespace NJsonConverters {
- class IJsonSerializable {
- public:
- virtual NSc::TValue ToTValue() const = 0;
- virtual void FromTValue(const NSc::TValue&, const bool validate) = 0;
- const TString ToJson(const bool sort = false) const {
- return ToTValue().ToJson(sort);
- }
- void FromJson(const TStringBuf& json, const bool validate = false) {
- NSc::TValue v = NSc::TValue::FromJson(json);
- FromTValue(v, validate);
- }
- virtual ~IJsonSerializable() = default;
- };
- //////////////////////////////////////////////////////////////////////
- // fwd declarations
- //////////////////////////////////////////////////////////////////////
- //TVector
- template <typename T, typename A>
- NSc::TValue ToTValue(const TVector<T, A>& x);
- template <typename T, typename A>
- void FromTValue(const NSc::TValue& x, TVector<T, A>& out, const bool validate);
- //THashMap
- template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
- NSc::TValue ToTValue(const THashMap<Key, T, HashFcn, EqualKey, Alloc>& x);
- template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
- void FromTValue(const NSc::TValue& x, THashMap<Key, T, HashFcn, EqualKey, Alloc>& out, const bool validate);
- //TMap
- template <class K, class V, class Less, class A>
- NSc::TValue ToTValue(const TMap<K, V, Less, A>& x);
- template <class K, class V, class Less, class A>
- void FromTValue(const NSc::TValue& x, TMap<K, V, Less, A>& out, const bool validate);
- //THashSet
- template <class V, class H, class E, class A>
- NSc::TValue ToTValue(const THashSet<V, H, E, A>& x);
- template <class V, class H, class E, class A>
- void FromTValue(const NSc::TValue& x, THashSet<V, H, E, A>& out, const bool validate);
- //TSet
- template <class K, class L, class A>
- NSc::TValue ToTValue(const TSet<K, L, A>& x);
- template <class K, class L, class A>
- void FromTValue(const NSc::TValue& x, TSet<K, L, A>& out, const bool validate);
- //std::pair
- template <class T1, class T2>
- NSc::TValue ToTValue(const std::pair<T1, T2>& x);
- template <class T1, class T2>
- void FromTValue(const NSc::TValue& x, std::pair<T1, T2>& out, const bool validate);
- //////////////////////////////////////////////////////////////////////
- // simple From, To helpers
- //////////////////////////////////////////////////////////////////////
- template <typename T, bool HasSerializer>
- struct TValueAndStrokaConv {};
- template <typename T>
- struct TValueAndStrokaConv<T, 0> {
- static NSc::TValue ToTValue(const T& x) {
- return NSc::TValue(x);
- }
- static void FromTValue(const NSc::TValue& x, T& out, const bool) {
- out = x;
- }
- static TString ToString(const T& x) {
- return ::ToString(x);
- }
- static void FromString(const TStringBuf& str, T& res, const bool) {
- res = ::FromString<T>(str);
- }
- };
- template <typename T>
- struct TValueAndStrokaConv<T, 1> {
- static NSc::TValue ToTValue(const T& x) {
- return x.ToTValue();
- }
- static void FromTValue(const NSc::TValue& x, T& out, const bool validate) {
- out.FromTValue(x, validate);
- }
- static TString ToString(const T& x) {
- return x.ToJson();
- }
- static void FromString(const TStringBuf& str, T& res, const bool validate) {
- res.FromJson(str, validate);
- }
- };
- template <typename T>
- NSc::TValue ToTValue(const T& x) {
- return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::ToTValue(x);
- }
- template <typename T>
- void FromTValue(const NSc::TValue& x, T& out, const bool validate) {
- return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::FromTValue(x, out, validate);
- }
- template <typename T>
- T FromTValue(const NSc::TValue& x, const bool validate) {
- T ret;
- FromTValue(x, ret, validate);
- return ret;
- }
- template <typename T>
- TString ToString(const T& x) {
- return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::ToString(x);
- }
- template <typename T>
- void FromString(const TStringBuf& str, T& res, const bool validate) {
- return TValueAndStrokaConv<T, std::is_base_of<IJsonSerializable, T>::value>::FromString(str, res, validate);
- }
- template <typename T>
- T FromString(const TStringBuf& str, bool validate) {
- T ret;
- FromString(str, ret, validate);
- return ret;
- }
- namespace NPrivate {
- template <typename T>
- NSc::TValue ToTValueDict(const T& dict) {
- NSc::TValue out;
- out.SetDict();
- for (typename T::const_iterator it = dict.begin(); it != dict.end(); ++it) {
- out[ToString(it->first)] = NJsonConverters::ToTValue(it->second);
- }
- return out;
- }
- template <typename T>
- void FromTValueDict(const NSc::TValue& x, T& out, bool validate) {
- typedef typename T::key_type TKey;
- typedef typename T::mapped_type TMapped;
- if (validate)
- Y_ENSURE(x.IsDict() || x.IsNull(), "not valid input scheme");
- out.clear();
- if (x.IsDict()) {
- const NSc::TDict& dict = x.GetDict();
- for (const auto& it : dict) {
- TKey key = NJsonConverters::FromString<TKey>(it.first, validate);
- TMapped val = NJsonConverters::FromTValue<TMapped>(it.second, validate);
- out.insert(std::pair<TKey, TMapped>(key, val));
- }
- }
- }
- template <typename T>
- NSc::TValue ToTValueSet(const T& set) {
- NSc::TValue out;
- out.SetDict();
- for (typename T::const_iterator it = set.begin(); it != set.end(); ++it) {
- out[ToString(*it)] = NSc::Null();
- }
- return out;
- }
- template <typename T>
- void FromTValueSet(const NSc::TValue& x, T& out, const bool validate) {
- typedef typename T::key_type TKey;
- if (validate)
- Y_ENSURE(x.IsDict() || x.IsNull(), "not valid input scheme");
- out.clear();
- if (x.IsDict()) {
- const NSc::TDict& dict = x.GetDict();
- for (const auto& it : dict) {
- TKey key;
- NJsonConverters::FromString<TKey>(it.first, key, validate);
- out.insert(key);
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // TVector
- //////////////////////////////////////////////////////////////////////
- template <typename T, typename A>
- NSc::TValue ToTValue(const TVector<T, A>& x) {
- NSc::TValue out;
- out.SetArray();
- for (typename TVector<T, A>::const_iterator it = x.begin(); it != x.end(); ++it)
- out.Push(NJsonConverters::ToTValue(*it));
- return out;
- }
- template <typename T, typename A>
- void FromTValue(const NSc::TValue& x, TVector<T, A>& out, const bool validate) {
- if (validate)
- Y_ENSURE(x.IsArray() || x.IsNull(), "not valid input scheme");
- out.clear();
- if (x.IsArray()) {
- const NSc::TArray& arr = x.GetArray();
- out.reserve(arr.size());
- for (const auto& it : arr) {
- T val;
- NJsonConverters::FromTValue(it, val, validate);
- out.push_back(val);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // THashMap & TMap
- //////////////////////////////////////////////////////////////////////
- template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
- NSc::TValue ToTValue(const THashMap<Key, T, HashFcn, EqualKey, Alloc>& x) {
- return NPrivate::ToTValueDict(x);
- }
- template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
- void FromTValue(const NSc::TValue& x, THashMap<Key, T, HashFcn, EqualKey, Alloc>& out, const bool validate) {
- NPrivate::FromTValueDict(x, out, validate);
- }
- template <class K, class V, class Less, class A>
- NSc::TValue ToTValue(const TMap<K, V, Less, A>& x) {
- return NPrivate::ToTValueDict(x);
- }
- template <class K, class V, class Less, class A>
- void FromTValue(const NSc::TValue& x, TMap<K, V, Less, A>& out, const bool validate) {
- NPrivate::FromTValueDict(x, out, validate);
- }
- //////////////////////////////////////////////////////////////////////
- // THashSet & TSet
- //////////////////////////////////////////////////////////////////////
- template <class V, class H, class E, class A>
- NSc::TValue ToTValue(const THashSet<V, H, E, A>& x) {
- return NPrivate::ToTValueSet(x);
- }
- template <class V, class H, class E, class A>
- void FromTValue(const NSc::TValue& x, THashSet<V, H, E, A>& out, const bool validate) {
- NPrivate::FromTValueSet(x, out, validate);
- }
- template <class K, class L, class A>
- NSc::TValue ToTValue(const TSet<K, L, A>& x) {
- return NPrivate::ToTValueSet(x);
- }
- template <class K, class L, class A>
- void FromTValue(const NSc::TValue& x, TSet<K, L, A>& out, const bool validate) {
- NPrivate::FromTValueSet(x, out, validate);
- }
- //////////////////////////////////////////////////////////////////////
- // std::pair
- //////////////////////////////////////////////////////////////////////
- template <class T1, class T2>
- NSc::TValue ToTValue(const std::pair<T1, T2>& x) {
- NSc::TValue out;
- out.SetArray();
- out.Push(NJsonConverters::ToTValue(x.first));
- out.Push(NJsonConverters::ToTValue(x.second));
- return out;
- }
- template <class T1, class T2>
- void FromTValue(const NSc::TValue& x, std::pair<T1, T2>& out, const bool validate) {
- if (validate)
- Y_ENSURE(x.IsArray() || x.IsNull(), "not valid input scheme");
- if (x.IsArray()) {
- const NSc::TArray& arr = x.GetArray();
- if (arr.size() == 2) {
- T1 val0;
- T2 val1;
- NJsonConverters::FromTValue(arr[0], val0, validate);
- NJsonConverters::FromTValue(arr[1], val1, validate);
- out.first = val0;
- out.second = val1;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////
- // global user functions
- //////////////////////////////////////////////////////////////////////
- template <typename T>
- TString ToJson(const T& val, const bool sort = false) {
- return NJsonConverters::ToTValue(val).ToJson(sort);
- }
- template <typename T>
- T FromJson(const TStringBuf& json, bool validate = false) {
- NSc::TValue v = NSc::TValue::FromJson(json);
- T ret;
- NJsonConverters::FromTValue(v, ret, validate);
- return ret;
- }
- }
|