#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