tsl-devkit/lsp-server/src/codec/facade.cppm

149 lines
4.1 KiB
C++

module;
import glaze;
export module lsp.codec.facade;
import std;
import lsp.codec.transformer;
import lsp.protocol.common.basic_types;
export namespace lsp::codec
{
template<typename T>
std::optional<T> Deserialize(const std::string& json);
template<typename T>
std::optional<std::string> Serialize(const T& obj);
inline constexpr auto ToLSPAny = [](const auto& value) {
return LSPAnyConverter::ToLSPAny(value);
};
inline constexpr auto FromLSPAny = []<typename T>(const auto& input) -> T {
using InputType = std::decay_t<decltype(input)>;
protocol::LSPAny any;
if constexpr (std::is_same_v<InputType, std::variant<protocol::LSPArray, protocol::LSPObject>>)
any = std::visit([](const auto& v) -> protocol::LSPAny { return v; }, input);
else
any = input;
return LSPAnyConverter::FromLSPAny<T>(any);
};
namespace check
{
bool IsObject(const protocol::LSPAny& any);
bool IsArray(const protocol::LSPAny& any);
bool IsString(const protocol::LSPAny& any);
bool IsNumber(const protocol::LSPAny& any);
bool IsBool(const protocol::LSPAny& any);
bool IsNull(const protocol::LSPAny& any);
}
namespace debug
{
std::string GetTypeName(const protocol::LSPAny& any);
std::string GetIdString(const std::variant<int, std::string>& id);
}
}
namespace lsp::codec
{
// ==================== JSON 序列化/反序列化 ====================
template<typename T>
std::optional<T> Deserialize(const std::string& json)
{
T obj;
auto ce = glz::read_json(obj, json);
if (ce)
return std::nullopt;
else
return obj;
}
template<typename T>
std::optional<std::string> Serialize(const T& obj)
{
std::string json;
auto ce = glz::write_json(obj, json);
if (ce)
return std::nullopt;
else
return json;
}
// ==================== 类型检查 ====================
namespace check
{
inline bool IsObject(const protocol::LSPAny& any)
{
return any.Is<protocol::LSPObject>();
}
inline bool IsArray(const protocol::LSPAny& any)
{
return any.Is<protocol::LSPArray>();
}
inline bool IsString(const protocol::LSPAny& any)
{
return any.Is<protocol::string>();
}
inline bool IsNumber(const protocol::LSPAny& any)
{
return any.Is<protocol::integer>() || any.Is<protocol::uinteger>() || any.Is<protocol::decimal>();
}
inline bool IsBool(const protocol::LSPAny& any)
{
return any.Is<protocol::boolean>();
}
inline bool IsNull(const protocol::LSPAny& any)
{
return any.Is<std::nullptr_t>();
}
}
// ==================== 调试工具 ====================
namespace debug
{
inline std::string GetTypeName(const protocol::LSPAny& any)
{
if (any.Is<protocol::LSPObject>())
return "LSPObject";
if (any.Is<protocol::LSPArray>())
return "LSPArray";
if (any.Is<protocol::string>())
return "string";
if (any.Is<protocol::integer>())
return "integer";
if (any.Is<protocol::uinteger>())
return "uinteger";
if (any.Is<protocol::decimal>())
return "decimal";
if (any.Is<protocol::boolean>())
return "boolean";
if (any.Is<std::nullptr_t>())
return "null";
return "unknown";
}
inline std::string GetIdString(const std::variant<int, std::string>& id)
{
return std::visit([](const auto& value) -> std::string {
if constexpr (std::is_same_v<std::decay_t<decltype(value)>, int>)
return std::to_string(value);
else
return value;
},
id);
}
}
}