aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/scheme/scheme_cast.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/scheme/scheme_cast.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/scheme/scheme_cast.h')
-rw-r--r--library/cpp/scheme/scheme_cast.h321
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;
+ }
+}