#pragma once #include #include #include #include #define BRUSSEL_JSON_GET(object, name, type, out, failAction) \ { \ auto it = (object).FindMember(name); \ if (it == (object).MemberEnd()) failAction; \ auto& value = it->value; \ if (!value.Is()) failAction; \ (out) = value.Get(); \ } #define BRUSSEL_JSON_GET_DEFAULT(object, name, type, out, theDefault) \ do { \ auto it = (object).FindMember(name); \ if (it == (object).MemberEnd()) { \ (out) = theDefault; \ break; \ } \ auto& value = it->value; \ if (!value.Is()) { \ (out) = theDefault; \ break; \ } \ (out) = value.Get(); \ } while (0); namespace rapidjson { inline const Value* GetProperty(const Value& value, std::string_view name) { for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) { if (it->name.GetStringLength() != name.size()) continue; if (std::memcmp(it->name.GetString(), name.data(), name.size())) continue; return &it->value; } return nullptr; } inline const Value* GetProperty(const Value& value, Type type, std::string_view name) { for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) { if (it->name.GetStringLength() != name.size()) continue; if (it->value.GetType() != type) continue; if (std::memcmp(it->name.GetString(), name.data(), name.size())) continue; return &it->value; } return nullptr; } inline std::string_view AsStringView(const Value& value) { return std::string_view(value.GetString(), value.GetStringLength()); } inline std::string_view AsStringView(const GenericStringRef& strRef) { return std::string_view(strRef.s, strRef.length); } inline std::string AsString(const Value& value) { return std::string(value.GetString(), value.GetStringLength()); } inline std::string AsString(const GenericStringRef& strRef) { return std::string(strRef.s, strRef.length); } // RapidJson itself already provides std::string and const char* overloads inline GenericStringRef StringRef(std::string_view str) { return GenericStringRef( str.data() ? str.data() : "", str.size()); } template rapidjson::Value WriteVectorPrimitives(rapidjson::Document& root, TIter begin, TSentienl end) { using TElement = typename TIter::value_type; rapidjson::Value list; while (begin != end) { if constexpr (std::is_same_v) { auto& elm = *begin; list.PushBack(rapidjson::Value(elm.c_str(), elm.size()), root.GetAllocator()); } else { list.PushBack(*begin, root.GetAllocator()); } ++begin; } return list; } template bool ReadVectorPrimitives(const rapidjson::Value& value, TContainer& list) { using TElement = typename TContainer::value_type; if (!value.IsArray()) return false; list.reserve(value.Size()); for (auto& elm : value.GetArray()) { if (!elm.Is()) return {}; list.push_back(elm.Get()); } return true; } } // namespace rapidjson