123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #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 << ')';
- }
- }
|