#pragma once #include "LibLsp/JsonRpc/serializer.h" #include <string> #include "LibLsp/JsonRpc/message.h" namespace lsp { struct Any { //! Type of JSON value enum Type { kUnKnown = -1, kNullType = 0, //!< null kFalseType = 1, //!< false kTrueType = 2, //!< true kObjectType = 3, //!< object kArrayType = 4, //!< array kStringType = 5, //!< string kNumberType = 6 //!< number }; template<typename T> bool Get(T& value); template<typename T> void Set(T& value); int GuessType(); int GetType(); void Set(std::unique_ptr<LspMessage> value); void SetJsonString(std::string&& _data, Type _type); void SetJsonString(std::string const& _data, Type _type); std::string const& Data() const { return data; } void swap(Any& arg) noexcept; /* *Example for GetFromMap struct A{ std::string visitor; bool verbose; } REFLECT_MAP_TO_STRUCT(A,visitor,verbose) std::string data = "{\"visitor\":\"default\",\"verbose\":\"true\"}; lsp:Any any; any.SetJsonString(data, static_cast<lsp::Any::Type>(-1)); A a_object; any.GetFromMap(a_object); */ template<typename T> bool GetFromMap(T& value); template<typename T> bool GetForMapHelper(T& value); bool GetForMapHelper(std::string& value); bool GetForMapHelper(optional<std::string>& value); private: std::unique_ptr<Reader> GetReader(); std::unique_ptr<Writer> GetWriter() const; void SetData(std::unique_ptr<Writer>&); std::string data; int jsonType = kUnKnown; }; }; // namespace lsp extern void Reflect(Reader& visitor, lsp::Any& value); extern void Reflect(Writer& visitor, lsp::Any& value); template<typename T> void ReflectMember(std::map<std::string, lsp::Any>& visitor, char const* name, T& value) { auto it = visitor.find(name); if (it != visitor.end()) { it->second.GetForMapHelper(value); } } template<typename T> void ReflectMember(std::map<std::string, std::string>& visitor, char const* name, T& value) { auto it = visitor.find(name); if (it != visitor.end()) { lsp::Any any; any.SetJsonString(it->second, static_cast<lsp::Any::Type>(-1)); any.Get(value); } } #define REFLECT_MAP_TO_STRUCT(type, ...) \ template<typename TVisitor> \ void ReflectMap(TVisitor& visitor, type& value) \ { \ MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \ } namespace lsp { template<typename T> bool Any::Get(T& value) { auto const visitor = GetReader(); Reflect(*visitor, value); return true; } template<typename T> void Any::Set(T& value) { auto visitor = GetWriter(); Reflect(*visitor, value); SetData(visitor); } template<typename T> bool Any::GetFromMap(T& value) { auto const visitor = GetReader(); std::map<std::string, lsp::Any> _temp; Reflect(*visitor, _temp); ReflectMap(_temp, value); return true; } template<typename T> bool Any::GetForMapHelper(T& value) { jsonType = GetType(); if (jsonType == kStringType) { auto copy = data; copy.erase(copy.find_last_not_of('"') + 1); copy.erase(0, copy.find_first_not_of('"')); lsp::Any any; any.SetJsonString(copy, kUnKnown); any.Get(value); } else { Get(value); } return true; } } // namespace lsp