aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/config/value.cpp
diff options
context:
space:
mode:
authormonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
committermonster <monster@ydb.tech>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/config/value.cpp
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
downloadydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz
fix ya.make
Diffstat (limited to 'library/cpp/config/value.cpp')
-rw-r--r--library/cpp/config/value.cpp292
1 files changed, 292 insertions, 0 deletions
diff --git a/library/cpp/config/value.cpp b/library/cpp/config/value.cpp
new file mode 100644
index 0000000000..776cd2b66c
--- /dev/null
+++ b/library/cpp/config/value.cpp
@@ -0,0 +1,292 @@
+#include "value.h"
+#include "config.h"
+
+#include <library/cpp/string_utils/relaxed_escaper/relaxed_escaper.h>
+
+#include <util/generic/algorithm.h>
+#include <util/system/type_name.h>
+#include <util/generic/singleton.h>
+#include <util/string/cast.h>
+#include <util/string/strip.h>
+#include <util/string/type.h>
+
+using namespace NConfig;
+
+namespace {
+ template <class T>
+ class TValue: public IValue {
+ public:
+ inline TValue(const T& t)
+ : T_(t)
+ {
+ }
+
+ bool IsA(const std::type_info& info) const override {
+ return info == typeid(T);
+ }
+
+ TString TypeName() const override {
+ return ::TypeName<T>();
+ }
+
+ void* Ptr() const override {
+ return (void*)&T_;
+ }
+
+ void ToJson(IOutputStream& out) const override {
+ out << AsString();
+ }
+
+ bool AsBool() const override {
+ return (bool)AsDouble();
+ }
+
+ protected:
+ T T_;
+ };
+
+ class TNullValue: public TValue<TNull> {
+ public:
+ inline TNullValue()
+ : TValue<TNull>(TNull())
+ {
+ Ref();
+ }
+
+ double AsDouble() const override {
+ return 0;
+ }
+
+ ui64 AsUInt() const override {
+ return 0;
+ }
+
+ i64 AsInt() const override {
+ return 0;
+ }
+
+ TString AsString() const override {
+ return TString();
+ }
+
+ void ToJson(IOutputStream& out) const override {
+ out << "null";
+ }
+
+ TString TypeName() const override {
+ return "null";
+ }
+ };
+
+ template <class T>
+ class TNumericValue: public TValue<T> {
+ public:
+ inline TNumericValue(const T& t)
+ : TValue<T>(t)
+ {
+ }
+
+ double AsDouble() const override {
+ return this->T_;
+ }
+
+ ui64 AsUInt() const override {
+ return this->T_;
+ }
+
+ i64 AsInt() const override {
+ return this->T_;
+ }
+ };
+
+ class TBoolValue: public TNumericValue<bool> {
+ public:
+ inline TBoolValue(bool v)
+ : TNumericValue<bool>(v)
+ {
+ }
+
+ TString AsString() const override {
+ return T_ ? "true" : "false";
+ }
+ };
+
+ template <class T>
+ class TArithmeticValue: public TNumericValue<T> {
+ public:
+ inline TArithmeticValue(T v)
+ : TNumericValue<T>(v)
+ {
+ }
+
+ TString AsString() const override {
+ return ToString(this->T_);
+ }
+ };
+
+ class TStringValue: public TValue<TString> {
+ public:
+ inline TStringValue(const TString& v)
+ : TValue<TString>(v)
+ {
+ }
+
+ template <class T>
+ inline T AsT() const {
+ const TStringBuf s = StripString(TStringBuf(T_));
+
+ if (IsTrue(s)) {
+ return true;
+ }
+
+ if (IsFalse(s)) {
+ return false;
+ }
+
+ return FromString<T>(s);
+ }
+
+ double AsDouble() const override {
+ return AsT<double>();
+ }
+
+ ui64 AsUInt() const override {
+ return AsT<ui64>();
+ }
+
+ i64 AsInt() const override {
+ return AsT<i64>();
+ }
+
+ TString AsString() const override {
+ return T_;
+ }
+
+ void ToJson(IOutputStream& out) const override {
+ NEscJ::EscapeJ<true, true>(T_, out);
+ }
+
+ TString TypeName() const override {
+ return "string";
+ }
+ };
+
+ template <class T>
+ class TContainer: public TValue<T> {
+ public:
+ inline TContainer(const T& t)
+ : TValue<T>(t)
+ {
+ }
+
+ double AsDouble() const override {
+ NCfgPrivate::ReportTypeMismatch(this->TypeName(), "double");
+ }
+
+ ui64 AsUInt() const override {
+ NCfgPrivate::ReportTypeMismatch(this->TypeName(), "uint");
+ }
+
+ i64 AsInt() const override {
+ NCfgPrivate::ReportTypeMismatch(this->TypeName(), "int");
+ }
+
+ bool AsBool() const override {
+ NCfgPrivate::ReportTypeMismatch(this->TypeName(), "bool");
+ }
+
+ TString AsString() const override {
+ NCfgPrivate::ReportTypeMismatch(this->TypeName(), "string");
+ }
+ };
+
+ class TArrayValue: public TContainer<TArray> {
+ public:
+ inline TArrayValue(const TArray& v)
+ : TContainer<TArray>(v)
+ {
+ }
+
+ void ToJson(IOutputStream& s) const override {
+ s << "[";
+
+ for (TArray::const_iterator it = T_.begin(); it != T_.end(); ++it) {
+ if (it != T_.begin()) {
+ s << ",";
+ }
+
+ it->ToJson(s);
+ }
+
+ s << "]";
+ }
+
+ TString TypeName() const override {
+ return "array";
+ }
+ };
+
+ class TDictValue: public TContainer<TDict> {
+ public:
+ inline TDictValue(const TDict& v)
+ : TContainer<TDict>(v)
+ {
+ }
+
+ void ToJson(IOutputStream& s) const override {
+ s << "{";
+
+ TVector<TStringBuf> buf;
+ buf.reserve(T_.size());
+ for (const auto& t : T_) {
+ buf.push_back(t.first);
+ }
+ Sort(buf.begin(), buf.end());
+ for (TVector<TStringBuf>::const_iterator kit = buf.begin(); kit != buf.end(); ++kit) {
+ TStringBuf key = *kit;
+ TDict::const_iterator it = T_.find(key);
+
+ if (kit != buf.begin()) {
+ s << ",";
+ }
+
+ NEscJ::EscapeJ<true, true>(key, s);
+
+ s << ":";
+
+ it->second.ToJson(s);
+ }
+
+ s << "}";
+ }
+
+ TString TypeName() const override {
+ return "dict";
+ }
+ };
+}
+
+#define DECLARE(type1, type2) \
+ IValue* ConstructValueImpl(const type2& t) { \
+ return new type1(t); \
+ }
+
+namespace NConfig {
+ namespace NCfgPrivate {
+ DECLARE(TBoolValue, bool)
+ DECLARE(TArithmeticValue<double>, double)
+ DECLARE(TArithmeticValue<i64>, i64)
+ DECLARE(TArithmeticValue<ui64>, ui64)
+ DECLARE(TStringValue, TString)
+ DECLARE(TArrayValue, TArray)
+ DECLARE(TDictValue, TDict)
+ }
+
+ IValue* Null() {
+ return Singleton<TNullValue>();
+ }
+
+ [[noreturn]] void NCfgPrivate::ReportTypeMismatch(TStringBuf realType, TStringBuf expectedType) {
+ ythrow TTypeMismatch() << "type mismatch (real: " << realType << ", expected: " << expectedType << ')';
+ }
+}