NeoVim + LSP shows diagnostic for external crates

I'm using rust-tool.vim and ChatGpt cooked up this solution for me based on telling RA that the root_dir can only be the current workspace. Should be portable as long as the lsp is rust-analyzer.

First define these helpers

local function ensure_uri_scheme(uri)
    if not vim.startswith(uri, "file://") then
        return "file://" .. uri
    end
    return uri
end

local function is_in_workspace(uri)
    uri = ensure_uri_scheme(uri)
    local path = vim.uri_to_fname(uri)
    local workspace_dir = vim.fn.getcwd()

    return vim.startswith(path, workspace_dir)
end

local function filter_diagnostics(diagnostics)
    local filtered_diagnostics = {}
    for _, diagnostic in ipairs(diagnostics) do
        if is_in_workspace(diagnostic.source) then
            table.insert(filtered_diagnostics, diagnostic)
        end
    end
    return filtered_diagnostics
end

Then configure the root_dir option in lspconfig or lsp zero. In my case I just used rust-tools config directly and it worked.

local lspconfig = require('lspconfig')
let rt = require('rust-tools')
rt.setup({
    --....
    --....
    server = {
       root_dir = function(startpath)
            local startpath_uri = vim.uri_from_fname(startpath)
            if not is_in_workspace(startpath) then
                return nil
            end

            return lspconfig.util.root_pattern("Cargo.toml", "rust-project.json")(startpath)
      end,
    }
})

It also gave me another option I can set with a function that does diagnostic filtering based on if the file is from the workspace. But I'm satisfied with RA being disabled all together with the above solution. Here is the filtering snippet

local lspconfig = require('lspconfig')
let rt = require('rust-tools')
rt.setup({
     --....
     --....
     server = {
          handlers = {
            ["textDocument/publishDiagnostics"] = function(err, method, result, client_id, bufnr, config)
            if not result or not result.uri then
                return
            end

            local uri = result.uri
            local bufnr = vim.uri_to_bufnr(uri)

            if not bufnr then
                return
            end

            if is_in_workspace(uri) then
                local diagnostics = vim.lsp.diagnostic.to_severity(result.diagnostics)
                diagnostics = filter_diagnostics(diagnostics)
                vim.lsp.diagnostic.save(diagnostics, bufnr, client_id)
                if vim.api.nvim_buf_is_loaded(bufnr) then
                    vim.lsp.diagnostic.set_signs(diagnostics, bufnr, client_id)
                end
            end
        end;
    },
}
})