#include #include #include #include #include #include #include #include using integer = std::int32_t; using uinteger = std::uint32_t; using decimal = double; using boolean = bool; using string = std::string; // 前向声明 struct LSPAny; using LSPObject = std::map; using LSPArray = std::vector; using LSPAnyVariant = std::variant< LSPObject, LSPArray, string, decimal, // 放在前面,优先匹配数字 boolean, std::nullptr_t>; struct LSPAny { LSPAnyVariant value; // 默认构造函数 LSPAny() : value(nullptr) {} // 拷贝和移动构造函数 LSPAny(const LSPAny& other) : value(other.value) {} LSPAny(LSPAny&& other) noexcept : value(std::move(other.value)) {} // 针对每种支持的类型的构造函数 LSPAny(const std::map& val) : value(val) {} LSPAny(std::map&& val) : value(std::move(val)) {} LSPAny(const std::vector& val) : value(val) {} LSPAny(std::vector&& val) : value(std::move(val)) {} LSPAny(const string& val) : value(val) {} LSPAny(string&& val) : value(std::move(val)) {} LSPAny(const char* val) : value(string(val)) {} // 所有数字类型都转换为 decimal LSPAny(int val) : value(static_cast(val)) {} LSPAny(long val) : value(static_cast(val)) {} LSPAny(long long val) : value(static_cast(val)) {} LSPAny(unsigned int val) : value(static_cast(val)) {} LSPAny(unsigned long val) : value(static_cast(val)) {} LSPAny(unsigned long long val) : value(static_cast(val)) {} LSPAny(float val) : value(static_cast(val)) {} LSPAny(double val) : value(val) {} LSPAny(long double val) : value(static_cast(val)) {} LSPAny(boolean val) : value(val) {} LSPAny(std::nullptr_t) : value(nullptr) {} // 赋值操作符 LSPAny& operator=(const LSPAny& other) { value = other.value; return *this; } LSPAny& operator=(LSPAny&& other) noexcept { value = std::move(other.value); return *this; } // 针对每种支持的类型的赋值操作符 LSPAny& operator=(const std::map& val) { value = val; return *this; } LSPAny& operator=(std::map&& val) { value = std::move(val); return *this; } LSPAny& operator=(const std::vector& val) { value = val; return *this; } LSPAny& operator=(std::vector&& val) { value = std::move(val); return *this; } LSPAny& operator=(const string& val) { value = val; return *this; } LSPAny& operator=(string&& val) { value = std::move(val); return *this; } LSPAny& operator=(const char* val) { value = string(val); return *this; } // 所有数字类型都转换为 decimal LSPAny& operator=(int val) { value = static_cast(val); return *this; } LSPAny& operator=(long val) { value = static_cast(val); return *this; } LSPAny& operator=(long long val) { value = static_cast(val); return *this; } LSPAny& operator=(unsigned int val) { value = static_cast(val); return *this; } LSPAny& operator=(unsigned long val) { value = static_cast(val); return *this; } LSPAny& operator=(unsigned long long val) { value = static_cast(val); return *this; } LSPAny& operator=(float val) { value = static_cast(val); return *this; } LSPAny& operator=(double val) { value = val; return *this; } LSPAny& operator=(long double val) { value = static_cast(val); return *this; } LSPAny& operator=(boolean val) { value = val; return *this; } LSPAny& operator=(std::nullptr_t) { value = nullptr; return *this; } // 类型检查辅助函数 template bool is() const { return std::holds_alternative(value); } template T& get() { return std::get(value); } template const T& get() const { return std::get(value); } // 访问操作符 template auto visit(Visitor&& visitor) const { return std::visit(std::forward(visitor), value); } template auto visit(Visitor&& visitor) { return std::visit(std::forward(visitor), value); } }; // glaze 自动支持 std::variant,无需额外配置 namespace glz { template<> struct meta { using T = LSPAny; static constexpr auto value = &T::value; }; } // ===== 简单清晰的转换模板 ===== // 转换工具类 struct LSPConvert { // === 基本类型的转换(优先级最高) === // boolean static LSPAny ToLSPAny(boolean value) { return LSPAny(value); } // 整数类型 static LSPAny ToLSPAny(int value) { return LSPAny(value); } static LSPAny ToLSPAny(long value) { return LSPAny(value); } static LSPAny ToLSPAny(long long value) { return LSPAny(value); } static LSPAny ToLSPAny(unsigned int value) { return LSPAny(value); } static LSPAny ToLSPAny(unsigned long value) { return LSPAny(value); } static LSPAny ToLSPAny(unsigned long long value) { return LSPAny(value); } // 浮点类型 static LSPAny ToLSPAny(float value) { return LSPAny(value); } static LSPAny ToLSPAny(double value) { return LSPAny(value); } static LSPAny ToLSPAny(long double value) { return LSPAny(value); } // string static LSPAny ToLSPAny(const string& str) { return LSPAny(str); } static LSPAny ToLSPAny(const char* str) { return LSPAny(str); } // nullptr static LSPAny ToLSPAny(std::nullptr_t) { return LSPAny(nullptr); } // LSPAny 自身 static LSPAny ToLSPAny(const LSPAny& any) { return any; } // === 容器类型的转换 === // vector template static LSPAny ToLSPAny(const std::vector& vec) { LSPArray arr; arr.reserve(vec.size()); for (const auto& item : vec) { arr.push_back(ToLSPAny(item)); } return LSPAny(std::move(arr)); } // map template static LSPAny ToLSPAny(const std::map& map) { LSPObject obj; for (const auto& [key, value] : map) { obj[key] = ToLSPAny(value); } return LSPAny(std::move(obj)); } // optional template static LSPAny ToLSPAny(const std::optional& opt) { if (opt.has_value()) { return ToLSPAny(*opt); } return LSPAny(nullptr); } // === Struct 到 LSPAny 的转换(最低优先级) === template static typename std::enable_if< !std::is_arithmetic::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value, LSPAny>::type ToLSPAny(const T& obj) { // 序列化为 JSON 字符串 std::string json; auto ec = glz::write_json(obj, json); if (ec) { throw std::runtime_error("Failed to serialize to JSON"); } // 直接解析为 LSPAny LSPAny result; ec = glz::read_json(result, json); if (ec) { throw std::runtime_error("Failed to parse JSON to LSPAny"); } return result; } // === LSPAny 到基本类型的转换 === // boolean static boolean BoolFromLSPAny(const LSPAny& any) { if (!any.is()) { throw std::runtime_error("LSPAny is not a boolean"); } return any.get(); } // 数字类型 template static typename std::enable_if::value && !std::is_same::value, T>::type NumberFromLSPAny(const LSPAny& any) { if (!any.is()) { throw std::runtime_error("LSPAny is not a number"); } return static_cast(any.get()); } // string static string StringFromLSPAny(const LSPAny& any) { if (!any.is()) { throw std::runtime_error("LSPAny is not a string"); } return any.get(); } // === LSPAny 到容器类型的转换 === // vector template static std::vector VectorFromLSPAny(const LSPAny& any) { if (!any.is()) { throw std::runtime_error("LSPAny is not an array"); } const auto& arr = any.get(); std::vector result; result.reserve(arr.size()); for (const auto& item : arr) { result.push_back(FromLSPAny(item)); } return result; } // optional template static std::optional OptionalFromLSPAny(const LSPAny& any) { if (any.is()) { return std::nullopt; } return FromLSPAny(any); } // === LSPAny 到 Struct 的转换 === template static T FromLSPAny(const LSPAny& any) { return FromLSPAnyImpl(any); } private: // 内部实现,使用重载来处理不同类型 // boolean static boolean FromLSPAnyImpl(const LSPAny& any, boolean*) { return BoolFromLSPAny(any); } // string static string FromLSPAnyImpl(const LSPAny& any, string*) { return StringFromLSPAny(any); } // 数字类型 template static typename std::enable_if::value && !std::is_same::value, T>::type FromLSPAnyImpl(const LSPAny& any, T*) { return NumberFromLSPAny(any); } // LSPAny 自身 static LSPAny FromLSPAnyImpl(const LSPAny& any, LSPAny*) { return any; } // struct 类型 template static typename std::enable_if< !std::is_arithmetic::value && !std::is_same::value && !std::is_same::value, T>::type FromLSPAnyImpl(const LSPAny& any, T*) { // 序列化 LSPAny 为 JSON std::string json; auto ec = glz::write_json(any.value, json); if (ec) { throw std::runtime_error("Failed to serialize LSPAny to JSON"); } // 解析 JSON 到目标类型 T result; ec = glz::read_json(result, json); if (ec) { throw std::runtime_error("Failed to parse JSON to target type"); } return result; } // 通过指针类型来分派 template static T FromLSPAnyImpl(const LSPAny& any) { return FromLSPAnyImpl(any, static_cast(nullptr)); } }; // ===== 便利函数(可选) ===== // 基本类型的便利函数 inline LSPAny ToLSPAny(boolean value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(int value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(long value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(long long value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(unsigned int value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(unsigned long value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(unsigned long long value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(float value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(double value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(long double value) { return LSPConvert::ToLSPAny(value); } inline LSPAny ToLSPAny(const string& str) { return LSPConvert::ToLSPAny(str); } inline LSPAny ToLSPAny(const char* str) { return LSPConvert::ToLSPAny(str); } inline LSPAny ToLSPAny(std::nullptr_t) { return LSPConvert::ToLSPAny(nullptr); } inline LSPAny ToLSPAny(const LSPAny& any) { return LSPConvert::ToLSPAny(any); } // 容器类型的便利函数 template LSPAny ToLSPAny(const std::vector& vec) { return LSPConvert::ToLSPAny(vec); } template LSPAny ToLSPAny(const std::map& map) { return LSPConvert::ToLSPAny(map); } template LSPAny ToLSPAny(const std::optional& opt) { return LSPConvert::ToLSPAny(opt); } // struct 类型的便利函数 template typename std::enable_if< !std::is_arithmetic::value && !std::is_same::value && !std::is_same::value && !std::is_same::value && !std::is_same::value, LSPAny>::type ToLSPAny(const T& value) { return LSPConvert::ToLSPAny(value); } // FromLSPAny 便利函数 template T FromLSPAny(const LSPAny& any) { return LSPConvert::FromLSPAny(any); } // ===== 测试代码 ===== // 测试用的结构体 struct Message { string jsonrpc = "2.0"; string method; int id = 0; }; struct Position { int line; int character; }; struct Range { Position start; Position end; }; struct TextDocumentIdentifier { string uri; }; struct TextDocumentPositionParams { TextDocumentIdentifier textDocument; Position position; }; struct CompletionItem { string label; std::optional kind; std::optional detail; std::optional documentation; std::optional deprecated; std::optional preselect; std::optional sortText; std::optional filterText; std::optional insertText; }; // 为测试结构体提供 glaze 元数据 template<> struct glz::meta { using T = Message; static constexpr auto value = object( "jsonrpc", &T::jsonrpc, "method", &T::method, "id", &T::id); }; template<> struct glz::meta { using T = Position; static constexpr auto value = object( "line", &T::line, "character", &T::character); }; template<> struct glz::meta { using T = Range; static constexpr auto value = object( "start", &T::start, "end", &T::end); }; template<> struct glz::meta { using T = TextDocumentIdentifier; static constexpr auto value = object( "uri", &T::uri); }; template<> struct glz::meta { using T = TextDocumentPositionParams; static constexpr auto value = object( "textDocument", &T::textDocument, "position", &T::position); }; template<> struct glz::meta { using T = CompletionItem; static constexpr auto value = object( "label", &T::label, "kind", &T::kind, "detail", &T::detail, "documentation", &T::documentation, "deprecated", &T::deprecated, "preselect", &T::preselect, "sortText", &T::sortText, "filterText", &T::filterText, "insertText", &T::insertText); }; // 测试函数 #include void test_basic_conversion() { std::cout << "=== Testing Basic Conversion ===" << std::endl; // 测试 struct 转换 Message msg; msg.method = "textDocument/completion"; msg.id = 42; // Struct -> LSPAny LSPAny any = ToLSPAny(msg); // 序列化查看 std::string json; glz::write_json(any, json); std::cout << "Message as JSON: " << json << std::endl; // LSPAny -> Struct Message restored = FromLSPAny(any); std::cout << "Restored method: " << restored.method << std::endl; std::cout << "Restored id: " << restored.id << std::endl; } void test_vector_conversion() { std::cout << "\n=== Testing Vector Conversion ===" << std::endl; std::vector positions = { { 10, 5 }, { 20, 15 }, { 30, 25 } }; // Vector -> LSPAny LSPAny any = ToLSPAny(positions); std::string json; glz::write_json(any, json); std::cout << "Vector as JSON: " << json << std::endl; // LSPAny -> Vector auto restored = LSPConvert::VectorFromLSPAny(any); std::cout << "Restored " << restored.size() << " positions" << std::endl; } void test_optional_conversion() { std::cout << "\n=== Testing Optional Conversion ===" << std::endl; CompletionItem item; item.label = "std::vector"; item.kind = 1; item.detail = "template class vector"; LSPAny any = ToLSPAny(item); std::string json; glz::write_json(any, json); std::cout << "CompletionItem as JSON: " << json << std::endl; // 测试 null optional std::optional empty_opt; LSPAny null_any = ToLSPAny(empty_opt); glz::write_json(null_any, json); std::cout << "Empty optional as JSON: " << json << std::endl; } void test_mixed_usage() { std::cout << "\n=== Testing Mixed Usage ===" << std::endl; // 创建复杂对象 LSPObject obj; obj["message"] = ToLSPAny(Message{ "2.0", "test/method", 123 }); obj["position"] = ToLSPAny(Position{ 10, 20 }); obj["numbers"] = ToLSPAny(std::vector{ 1, 2, 3 }); obj["flag"] = LSPAny(true); obj["value"] = LSPAny(3.14); obj["text"] = LSPAny("Hello LSP"); obj["empty"] = LSPAny(nullptr); LSPAny root(obj); std::string json; glz::write_json(root, json); std::cout << "Complex object: " << json << std::endl; // 提取值 if (root.is()) { auto& root_obj = root.get(); Message msg = FromLSPAny(root_obj["message"]); std::cout << "Extracted message method: " << msg.method << std::endl; Position pos = FromLSPAny(root_obj["position"]); std::cout << "Extracted position: " << pos.line << ", " << pos.character << std::endl; } } int main() { try { test_basic_conversion(); test_vector_conversion(); test_optional_conversion(); test_mixed_usage(); std::cout << "\nAll tests completed!" << std::endl; } catch (const std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; return 1; } return 0; }