module; export module lsp.test.provider.fixtures; import std; export namespace lsp::test::provider { inline std::string& ExecutablePathStorage() { static std::string value; return value; } inline void SetExecutablePath(std::string value) { ExecutablePathStorage() = std::move(value); } inline const std::string& ExecutablePath() { return ExecutablePathStorage(); } inline std::filesystem::path FixturesRoot() { return std::filesystem::path(__FILE__).parent_path() / "fixtures"; } inline std::filesystem::path FixturePath(const std::string& name) { return FixturesRoot() / name; } inline std::string ToUri(const std::filesystem::path& path) { auto absolute = std::filesystem::absolute(path).generic_string(); #ifdef _WIN32 std::string normalized; normalized.reserve(absolute.size()); for (char ch : absolute) { normalized.push_back(ch == '\\' ? '/' : ch); } absolute = normalized; #endif if (!absolute.empty() && absolute.front() != '/') { absolute.insert(absolute.begin(), '/'); } return "file://" + absolute; } inline std::string ReadTextFile(const std::filesystem::path& path) { std::ifstream file(path, std::ios::binary); if (!file.is_open()) { throw std::runtime_error("Failed to open fixture: " + path.string()); } return std::string((std::istreambuf_iterator(file)), std::istreambuf_iterator()); } }