diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/scheme/scheme_cast.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/scheme_cast.h')
-rw-r--r-- | library/cpp/scheme/scheme_cast.h | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/library/cpp/scheme/scheme_cast.h b/library/cpp/scheme/scheme_cast.h new file mode 100644 index 00000000000..00839e8017c --- /dev/null +++ b/library/cpp/scheme/scheme_cast.h @@ -0,0 +1,321 @@ +#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(){}; + }; + ////////////////////////////////////////////////////////////////////// + // 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; + } +} |