config.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #pragma once
  2. #include "fwd.h"
  3. #include "value.h"
  4. #include <library/cpp/json/json_value.h>
  5. #include <util/generic/hash.h>
  6. #include <util/generic/ptr.h>
  7. #include <util/generic/deque.h>
  8. #include <util/system/type_name.h>
  9. #include <util/generic/vector.h>
  10. #include <util/generic/yexception.h>
  11. #include <util/generic/bt_exception.h>
  12. #include <util/ysaveload.h>
  13. class IInputStream;
  14. class IOutputStream;
  15. namespace NConfig {
  16. typedef THashMap<TString, NJson::TJsonValue> TGlobals;
  17. class TConfigError: public TWithBackTrace<yexception> {
  18. };
  19. class TConfigParseError: public TConfigError {
  20. };
  21. class TTypeMismatch: public TConfigError {
  22. };
  23. struct TArray;
  24. struct TDict;
  25. class TConfig {
  26. public:
  27. inline TConfig()
  28. : V_(Null())
  29. {
  30. }
  31. inline TConfig(IValue* v)
  32. : V_(v)
  33. {
  34. }
  35. TConfig(const TConfig& config) = default;
  36. TConfig& operator=(const TConfig& config) = default;
  37. template <class T>
  38. inline bool IsA() const {
  39. return V_->IsA(typeid(T));
  40. }
  41. inline bool IsNumeric() const {
  42. return IsA<double>() || IsA<i64>() || IsA<ui64>();
  43. }
  44. template <class T>
  45. inline const T& Get() const {
  46. return GetNonConstant<T>();
  47. }
  48. template <class T>
  49. inline T& GetNonConstant() const {
  50. if (this->IsA<T>()) {
  51. return *(T*)V_->Ptr();
  52. }
  53. if constexpr (std::is_same_v<T, ::NConfig::TArray>) {
  54. NCfgPrivate::ReportTypeMismatch(V_->TypeName(), "array");
  55. } else if constexpr (std::is_same_v<T, ::NConfig::TDict>) {
  56. NCfgPrivate::ReportTypeMismatch(V_->TypeName(), "dict");
  57. } else if constexpr (std::is_same_v<T, TString>) {
  58. NCfgPrivate::ReportTypeMismatch(V_->TypeName(), "string");
  59. } else {
  60. NCfgPrivate::ReportTypeMismatch(V_->TypeName(), ::TypeName<T>());
  61. }
  62. }
  63. template <class T>
  64. inline T As() const {
  65. return ValueAs<T>(V_.Get());
  66. }
  67. template <class T>
  68. inline T As(T def) const {
  69. return IsNull() ? def : As<T>();
  70. }
  71. inline bool IsNull() const noexcept {
  72. return V_.Get() == Null();
  73. }
  74. const TConfig& Or(const TConfig& r) const {
  75. return IsNull() ? r : *this;
  76. }
  77. //assume value is dict
  78. bool Has(const TStringBuf& key) const;
  79. const TConfig& operator[](const TStringBuf& key) const;
  80. const TConfig& At(const TStringBuf& key) const;
  81. //assume value is array
  82. const TConfig& operator[](size_t index) const;
  83. size_t GetArraySize() const;
  84. static TConfig FromIni(IInputStream& in, const TGlobals& g = TGlobals());
  85. static TConfig FromJson(IInputStream& in, const TGlobals& g = TGlobals());
  86. static TConfig FromLua(IInputStream& in, const TGlobals& g = TGlobals());
  87. //load yconf format. unsafe, but natural mapping
  88. static TConfig FromMarkup(IInputStream& in, const TGlobals& g = TGlobals());
  89. static TConfig FromStream(IInputStream& in, const TGlobals& g = TGlobals());
  90. inline void ToJson(IOutputStream& out) const {
  91. V_->ToJson(out);
  92. }
  93. void DumpJson(IOutputStream& out) const;
  94. void DumpLua(IOutputStream& out) const;
  95. static TConfig ReadJson(TStringBuf in, const TGlobals& g = TGlobals());
  96. static TConfig ReadLua(TStringBuf in, const TGlobals& g = TGlobals());
  97. static TConfig ReadMarkup(TStringBuf in, const TGlobals& g = TGlobals());
  98. static TConfig ReadIni(TStringBuf in, const TGlobals& g = TGlobals());
  99. void Load(IInputStream* stream);
  100. void Save(IOutputStream* stream) const;
  101. private:
  102. TIntrusivePtr<IValue> V_;
  103. };
  104. struct TArray: public TDeque<TConfig> {
  105. const TConfig& Index(size_t index) const;
  106. const TConfig& At(size_t index) const;
  107. };
  108. struct TDict: public THashMap<TString, TConfig> {
  109. const TConfig& Find(const TStringBuf& key) const;
  110. const TConfig& At(const TStringBuf& key) const;
  111. };
  112. THolder<IInputStream> CreatePreprocessor(const TGlobals& g, IInputStream& in);
  113. }