JsonNode.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * JsonNode.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "../filesystem/ResourcePath.h"
  12. VCMI_LIB_NAMESPACE_BEGIN
  13. class JsonNode;
  14. using JsonMap = std::map<std::string, JsonNode>;
  15. using JsonVector = std::vector<JsonNode>;
  16. struct Bonus;
  17. class CSelector;
  18. class CAddInfo;
  19. class ILimiter;
  20. class DLL_LINKAGE JsonNode
  21. {
  22. public:
  23. enum class JsonType
  24. {
  25. DATA_NULL,
  26. DATA_BOOL,
  27. DATA_FLOAT,
  28. DATA_STRING,
  29. DATA_VECTOR,
  30. DATA_STRUCT,
  31. DATA_INTEGER
  32. };
  33. private:
  34. using JsonData = std::variant<std::monostate, bool, double, std::string, JsonVector, JsonMap, int64_t>;
  35. JsonData data;
  36. public:
  37. /// free to use metadata fields
  38. std::string meta;
  39. /// meta-flags like override
  40. std::vector<std::string> flags;
  41. JsonNode() = default;
  42. /// Create single node with specified value
  43. explicit JsonNode(bool boolean);
  44. explicit JsonNode(int32_t number);
  45. explicit JsonNode(uint32_t number);
  46. explicit JsonNode(int64_t number);
  47. explicit JsonNode(double number);
  48. explicit JsonNode(const std::string & string);
  49. /// Create tree from Json-formatted input
  50. explicit JsonNode(const std::byte * data, size_t datasize);
  51. /// Create tree from JSON file
  52. explicit JsonNode(const JsonPath & fileURI);
  53. explicit JsonNode(const JsonPath & fileURI, const std::string & modName);
  54. explicit JsonNode(const JsonPath & fileURI, bool & isValidSyntax);
  55. bool operator == (const JsonNode &other) const;
  56. bool operator != (const JsonNode &other) const;
  57. void setMeta(const std::string & metadata, bool recursive = true);
  58. /// Convert node to another type. Converting to nullptr will clear all data
  59. void setType(JsonType Type);
  60. JsonType getType() const;
  61. bool isNull() const;
  62. bool isNumber() const;
  63. bool isString() const;
  64. bool isVector() const;
  65. bool isStruct() const;
  66. /// true if node contains not-null data that cannot be extended via merging
  67. /// used for generating common base node from multiple nodes (e.g. bonuses)
  68. bool containsBaseData() const;
  69. bool isCompact() const;
  70. /// removes all data from node and sets type to null
  71. void clear();
  72. /// returns bool or bool equivalent of string value if 'success' is true, or false otherwise
  73. bool TryBoolFromString(bool & success) const;
  74. /// non-const accessors, node will change type on type mismatch
  75. bool & Bool();
  76. double & Float();
  77. si64 & Integer();
  78. std::string & String();
  79. JsonVector & Vector();
  80. JsonMap & Struct();
  81. /// const accessors, will cause assertion failure on type mismatch
  82. bool Bool() const;
  83. ///float and integer allowed
  84. double Float() const;
  85. ///only integer allowed
  86. si64 Integer() const;
  87. const std::string & String() const;
  88. const JsonVector & Vector() const;
  89. const JsonMap & Struct() const;
  90. /// returns resolved "json pointer" (string in format "/path/to/node")
  91. const JsonNode & resolvePointer(const std::string & jsonPointer) const;
  92. JsonNode & resolvePointer(const std::string & jsonPointer);
  93. /// convert json tree into specified type. Json tree must have same type as Type
  94. /// Valid types: bool, string, any numeric, map and vector
  95. /// example: convertTo< std::map< std::vector<int> > >();
  96. template<typename Type>
  97. Type convertTo() const;
  98. //operator [], for structs only - get child node by name
  99. JsonNode & operator[](const std::string & child);
  100. const JsonNode & operator[](const std::string & child) const;
  101. JsonNode & operator[](size_t child);
  102. const JsonNode & operator[](size_t child) const;
  103. std::string toCompactString() const;
  104. std::string toString() const;
  105. std::vector<std::byte> toBytes() const;
  106. template <typename Handler> void serialize(Handler &h)
  107. {
  108. h & meta;
  109. h & flags;
  110. h & data;
  111. }
  112. };
  113. namespace JsonDetail
  114. {
  115. inline void convert(bool & value, const JsonNode & node)
  116. {
  117. value = node.Bool();
  118. }
  119. template<typename T>
  120. auto convert(T & value, const JsonNode & node) -> std::enable_if_t<std::is_integral_v<T>>
  121. {
  122. value = node.Integer();
  123. }
  124. template<typename T>
  125. auto convert(T & value, const JsonNode & node) -> std::enable_if_t<std::is_floating_point_v<T>>
  126. {
  127. value = node.Float();
  128. }
  129. inline void convert(std::string & value, const JsonNode & node)
  130. {
  131. value = node.String();
  132. }
  133. template <typename Type>
  134. void convert(std::map<std::string,Type> & value, const JsonNode & node)
  135. {
  136. value.clear();
  137. for (const JsonMap::value_type & entry : node.Struct())
  138. value.insert(entry.first, entry.second.convertTo<Type>());
  139. }
  140. template <typename Type>
  141. void convert(std::set<Type> & value, const JsonNode & node)
  142. {
  143. value.clear();
  144. for(const JsonVector::value_type & entry : node.Vector())
  145. {
  146. value.insert(entry.convertTo<Type>());
  147. }
  148. }
  149. template <typename Type>
  150. void convert(std::vector<Type> & value, const JsonNode & node)
  151. {
  152. value.clear();
  153. for(const JsonVector::value_type & entry : node.Vector())
  154. {
  155. value.push_back(entry.convertTo<Type>());
  156. }
  157. }
  158. }
  159. template<typename Type>
  160. Type JsonNode::convertTo() const
  161. {
  162. Type result;
  163. JsonDetail::convert(result, *this);
  164. return result;
  165. }
  166. VCMI_LIB_NAMESPACE_END