feat: support concurrency
This commit is contained in:
@@ -1,259 +1,259 @@
|
||||
#pragma once
|
||||
#include "./transformer.hpp"
|
||||
|
||||
namespace lsp::transform
|
||||
{
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(protocol::boolean value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(int value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned int value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned long long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(float value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(double value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long double value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const protocol::string& str)
|
||||
{
|
||||
return protocol::LSPAny(str);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const char* str)
|
||||
{
|
||||
return protocol::LSPAny(str);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(std::nullptr_t)
|
||||
{
|
||||
return protocol::LSPAny(nullptr);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const protocol::LSPAny& any)
|
||||
{
|
||||
return any;
|
||||
}
|
||||
|
||||
inline protocol::boolean LSPAnyConverter::ToBool(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::boolean>())
|
||||
throw ConversionError("LSPAny does not contain a boolean");
|
||||
return any.get<protocol::boolean>();
|
||||
}
|
||||
|
||||
inline protocol::string LSPAnyConverter::ToString(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::string>())
|
||||
throw ConversionError("LSPAny does not contain a string");
|
||||
return any.get<protocol::string>();
|
||||
}
|
||||
|
||||
inline protocol::LSPObject LSPAnyConverter::ToLSPObject(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPObject>())
|
||||
throw ConversionError("LSPAny does not contain LSPObject");
|
||||
return any.get<protocol::LSPObject>();
|
||||
}
|
||||
|
||||
inline protocol::LSPArray LSPAnyConverter::ToLSPArray(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPArray>())
|
||||
throw ConversionError("LSPAny does not contain LSPArray");
|
||||
return any.get<protocol::LSPArray>();
|
||||
}
|
||||
|
||||
// 模板实现
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::vector<T>& vec)
|
||||
{
|
||||
protocol::LSPArray arr;
|
||||
arr.reserve(vec.size());
|
||||
for (const auto& item : vec)
|
||||
arr.push_back(ToLSPAny(item));
|
||||
return protocol::LSPAny(std::move(arr));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::map<protocol::string, T>& map)
|
||||
{
|
||||
protocol::LSPObject obj;
|
||||
for (const auto& [key, value] : map)
|
||||
obj[key] = ToLSPAny(value);
|
||||
return protocol::LSPAny(std::move(obj));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::optional<T>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
return ToLSPAny(*opt);
|
||||
return protocol::LSPAny(nullptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::enable_if<is_user_struct<T>::value, protocol::LSPAny>::type
|
||||
LSPAnyConverter::ToLSPAny(const T& obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用glaze序列化为JSON字符串
|
||||
std::string json;
|
||||
auto ec = glz::write_json(obj, json);
|
||||
if (ec)
|
||||
{
|
||||
throw ConversionError("Failed to serialize struct to JSON: " + std::string(glz::format_error(ec, json)));
|
||||
}
|
||||
|
||||
// 直接解析为LSPAny
|
||||
protocol::LSPAny result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec)
|
||||
{
|
||||
throw ConversionError("Failed to parse JSON to LSPAny: " + std::string(glz::format_error(ec, json)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw ConversionError("struct to LSPAny conversion failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Fromprotocol::LSPAny 实现
|
||||
template<typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, protocol::boolean>::value, T>::type LSPAnyConverter::ToNumber(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::decimal>())
|
||||
throw ConversionError("LSPAny does not contain a number");
|
||||
return static_cast<T>(any.get<protocol::decimal>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::vector<T> LSPAnyConverter::ToVector(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPArray>())
|
||||
throw ConversionError("LSPAny does not contain an array");
|
||||
|
||||
const auto& arr = any.get<protocol::LSPArray>();
|
||||
std::vector<T> result;
|
||||
result.reserve(arr.size());
|
||||
for (const auto& item : arr)
|
||||
result.push_back(FromLSPAny<T>(item));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::optional<T> LSPAnyConverter::ToOptional(const protocol::LSPAny& any)
|
||||
{
|
||||
if (any.is<std::nullptr_t>())
|
||||
return std::nullopt;
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::enable_if<is_user_struct<T>::value, T>::type
|
||||
LSPAnyConverter::FromLSPAny(const protocol::LSPAny& any)
|
||||
{
|
||||
return FromLSPAnyImpl<T>(any);
|
||||
}
|
||||
|
||||
// 处理 std::optional<T>
|
||||
template<typename T, typename From>
|
||||
inline std::optional<T> LSPAnyConverter::As(const std::optional<From>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
return As<T>(*opt);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// 处理 std::variant<Ts...>
|
||||
template<typename T, typename... Ts>
|
||||
inline T LSPAnyConverter::As(const std::variant<Ts...>& var)
|
||||
{
|
||||
return std::visit([](const auto& val) -> T {
|
||||
return As<T>(val);
|
||||
}, var);
|
||||
}
|
||||
|
||||
// 处理 LSPObject
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::As(const protocol::LSPObject& obj)
|
||||
{
|
||||
protocol::LSPAny any(obj);
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// 处理 LSPArray
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::As(const protocol::LSPArray& arr)
|
||||
{
|
||||
protocol::LSPAny any(arr);
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// FromLSPAnyImpl 实现
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::FromLSPAnyImpl(const protocol::LSPAny& any)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 序列化LSPAny为JSON
|
||||
std::string json;
|
||||
auto ec = glz::write_json(any.value, json);
|
||||
if (ec)
|
||||
throw ConversionError("Failed to serialize LSPAny to JSON: " + std::string(glz::format_error(ec, json)));
|
||||
|
||||
// 解析JSON到目标类型
|
||||
T result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec)
|
||||
throw ConversionError("Failed to parse JSON to target type: " + std::string(glz::format_error(ec, json)));
|
||||
return result;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw ConversionError("LSPAny to struct conversion failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#pragma once
|
||||
#include "./transformer.hpp"
|
||||
|
||||
namespace lsp::transform
|
||||
{
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(protocol::boolean value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(int value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned int value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(unsigned long long value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(float value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(double value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(long double value)
|
||||
{
|
||||
return protocol::LSPAny(value);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const protocol::string& str)
|
||||
{
|
||||
return protocol::LSPAny(str);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const char* str)
|
||||
{
|
||||
return protocol::LSPAny(str);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(std::nullptr_t)
|
||||
{
|
||||
return protocol::LSPAny(nullptr);
|
||||
}
|
||||
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const protocol::LSPAny& any)
|
||||
{
|
||||
return any;
|
||||
}
|
||||
|
||||
inline protocol::boolean LSPAnyConverter::ToBool(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::boolean>())
|
||||
throw ConversionError("LSPAny does not contain a boolean");
|
||||
return any.get<protocol::boolean>();
|
||||
}
|
||||
|
||||
inline protocol::string LSPAnyConverter::ToString(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::string>())
|
||||
throw ConversionError("LSPAny does not contain a string");
|
||||
return any.get<protocol::string>();
|
||||
}
|
||||
|
||||
inline protocol::LSPObject LSPAnyConverter::ToLSPObject(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPObject>())
|
||||
throw ConversionError("LSPAny does not contain LSPObject");
|
||||
return any.get<protocol::LSPObject>();
|
||||
}
|
||||
|
||||
inline protocol::LSPArray LSPAnyConverter::ToLSPArray(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPArray>())
|
||||
throw ConversionError("LSPAny does not contain LSPArray");
|
||||
return any.get<protocol::LSPArray>();
|
||||
}
|
||||
|
||||
// 模板实现
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::vector<T>& vec)
|
||||
{
|
||||
protocol::LSPArray arr;
|
||||
arr.reserve(vec.size());
|
||||
for (const auto& item : vec)
|
||||
arr.push_back(ToLSPAny(item));
|
||||
return protocol::LSPAny(std::move(arr));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::map<protocol::string, T>& map)
|
||||
{
|
||||
protocol::LSPObject obj;
|
||||
for (const auto& [key, value] : map)
|
||||
obj[key] = ToLSPAny(value);
|
||||
return protocol::LSPAny(std::move(obj));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const std::optional<T>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
return ToLSPAny(*opt);
|
||||
return protocol::LSPAny(nullptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::enable_if<is_user_struct<T>::value, protocol::LSPAny>::type
|
||||
LSPAnyConverter::ToLSPAny(const T& obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 使用glaze序列化为JSON字符串
|
||||
std::string json;
|
||||
auto ec = glz::write_json(obj, json);
|
||||
if (ec)
|
||||
{
|
||||
throw ConversionError("Failed to serialize struct to JSON: " + std::string(glz::format_error(ec, json)));
|
||||
}
|
||||
|
||||
// 直接解析为LSPAny
|
||||
protocol::LSPAny result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec)
|
||||
{
|
||||
throw ConversionError("Failed to parse JSON to LSPAny: " + std::string(glz::format_error(ec, json)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw ConversionError("struct to LSPAny conversion failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
// Fromprotocol::LSPAny 实现
|
||||
template<typename T>
|
||||
inline typename std::enable_if<std::is_arithmetic<T>::value && !std::is_same<T, protocol::boolean>::value, T>::type LSPAnyConverter::ToNumber(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::decimal>())
|
||||
throw ConversionError("LSPAny does not contain a number");
|
||||
return static_cast<T>(any.get<protocol::decimal>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::vector<T> LSPAnyConverter::ToVector(const protocol::LSPAny& any)
|
||||
{
|
||||
if (!any.is<protocol::LSPArray>())
|
||||
throw ConversionError("LSPAny does not contain an array");
|
||||
|
||||
const auto& arr = any.get<protocol::LSPArray>();
|
||||
std::vector<T> result;
|
||||
result.reserve(arr.size());
|
||||
for (const auto& item : arr)
|
||||
result.push_back(FromLSPAny<T>(item));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::optional<T> LSPAnyConverter::ToOptional(const protocol::LSPAny& any)
|
||||
{
|
||||
if (any.is<std::nullptr_t>())
|
||||
return std::nullopt;
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline typename std::enable_if<is_user_struct<T>::value, T>::type
|
||||
LSPAnyConverter::FromLSPAny(const protocol::LSPAny& any)
|
||||
{
|
||||
return FromLSPAnyImpl<T>(any);
|
||||
}
|
||||
|
||||
// 处理 std::optional<T>
|
||||
template<typename T, typename From>
|
||||
inline std::optional<T> LSPAnyConverter::As(const std::optional<From>& opt)
|
||||
{
|
||||
if (opt.has_value())
|
||||
return As<T>(*opt);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// 处理 std::variant<Ts...>
|
||||
template<typename T, typename... Ts>
|
||||
inline T LSPAnyConverter::As(const std::variant<Ts...>& var)
|
||||
{
|
||||
return std::visit([](const auto& val) -> T {
|
||||
return As<T>(val);
|
||||
}, var);
|
||||
}
|
||||
|
||||
// 处理 LSPObject
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::As(const protocol::LSPObject& obj)
|
||||
{
|
||||
protocol::LSPAny any(obj);
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// 处理 LSPArray
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::As(const protocol::LSPArray& arr)
|
||||
{
|
||||
protocol::LSPAny any(arr);
|
||||
return FromLSPAny<T>(any);
|
||||
}
|
||||
|
||||
// FromLSPAnyImpl 实现
|
||||
template<typename T>
|
||||
inline T LSPAnyConverter::FromLSPAnyImpl(const protocol::LSPAny& any)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 序列化LSPAny为JSON
|
||||
std::string json;
|
||||
auto ec = glz::write_json(any.value, json);
|
||||
if (ec)
|
||||
throw ConversionError("Failed to serialize LSPAny to JSON: " + std::string(glz::format_error(ec, json)));
|
||||
|
||||
// 解析JSON到目标类型
|
||||
T result;
|
||||
ec = glz::read_json(result, json);
|
||||
if (ec)
|
||||
throw ConversionError("Failed to parse JSON to target type: " + std::string(glz::format_error(ec, json)));
|
||||
return result;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
throw ConversionError("LSPAny to struct conversion failed: " + std::string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user