#pragma once namespace lsp::transform { // ==================== ToLSPAny 实现 ==================== template inline protocol::LSPAny LSPAnyConverter::ToLSPAny(const T& value) { using Type = std::decay_t; // LSPAny 直接返回 if constexpr (std::is_same_v) { return value; } // LSPObject 直接返回 else if constexpr (std::is_same_v) { return protocol::LSPAny(value); } // LSPArray 直接返回 else if constexpr (std::is_same_v) { return protocol::LSPAny(value); } else if constexpr (std::is_same_v || std::is_same_v) { return protocol::LSPAny(protocol::string(value)); } // LSP 基本类型(boolean, string, decimal, nullptr) else if constexpr (is_lsp_basic_type_v) { return protocol::LSPAny(value); } // 整数类型(依赖 LSPAny 模板构造函数) else if constexpr (std::is_integral_v && !std::is_same_v) { return protocol::LSPAny(value); } // 浮点类型 else if constexpr (std::is_floating_point_v) { return protocol::LSPAny(value); } // vector → LSPArray else if constexpr (is_vector_v) { protocol::LSPArray arr; arr.reserve(value.size()); for (const auto& item : value) arr.push_back(ToLSPAny(item)); return protocol::LSPAny(std::move(arr)); } // map → LSPObject else if constexpr (is_map_v) { protocol::LSPObject obj; for (const auto& [key, val] : value) obj[key] = ToLSPAny(val); return protocol::LSPAny(std::move(obj)); } // optional → LSPAny or null else if constexpr (is_optional_v) { if (value.has_value()) return ToLSPAny(*value); return protocol::LSPAny(nullptr); } // 用户结构体 → LSPAny (通过 JSON) else if constexpr (is_user_struct_v) { return SerializeViaJson(value); } else { static_assert(!sizeof(Type), "Unsupported type for ToLSPAny"); } } // ==================== FromLSPAny 实现 ==================== template inline T LSPAnyConverter::FromLSPAny(const protocol::LSPAny& any) { using Type = std::decay_t; // LSPAny 直接返回 if constexpr (std::is_same_v) { return any; } // LSPObject 提取 else if constexpr (std::is_same_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain LSPObject"); return any.Get(); } // LSPArray 提取 else if constexpr (std::is_same_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain LSPArray"); return any.Get(); } // boolean 提取 else if constexpr (std::is_same_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain a boolean"); return any.Get(); } // string 提取 else if constexpr (std::is_same_v || std::is_same_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain a string"); return any.Get(); } // 数字类型提取 else if constexpr (std::is_arithmetic_v && !std::is_same_v) { return ExtractNumber(any); } // vector 提取 else if constexpr (is_vector_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain an array"); const auto& arr = any.Get(); Type result; result.reserve(arr.size()); for (const auto& item : arr) result.push_back(FromLSPAny(item)); return result; } // map 提取 else if constexpr (is_map_v) { if (!any.Is()) throw ConversionError("LSPAny does not contain an object"); const auto& obj = any.Get(); Type result; for (const auto& [key, val] : obj) result[key] = FromLSPAny(val); return result; } // optional 提取 else if constexpr (is_optional_v) { if (any.Is()) return std::nullopt; return FromLSPAny(any); } // 用户结构体提取(通过 JSON) else if constexpr (is_user_struct_v) { return ConvertViaJson(any); } else { static_assert(!sizeof(Type), "Unsupported type for FromLSPAny"); } } // ==================== 辅助工具实现 ==================== template inline T LSPAnyConverter::ExtractNumber(const protocol::LSPAny& any) { if (any.Is()) { return static_cast(any.Get()); } else if (any.Is()) { return static_cast(any.Get()); } else if (any.Is()) { return static_cast(any.Get()); } else { throw ConversionError("LSPAny does not contain a number (integer/uinteger/decimal)"); } } template inline T LSPAnyConverter::ConvertViaJson(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())); } } template inline protocol::LSPAny LSPAnyConverter::SerializeViaJson(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())); } } }