diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/config/value.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'library/cpp/config/value.cpp')
-rw-r--r-- | library/cpp/config/value.cpp | 292 |
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 << ')'; + } +} |