For those who don’t know, rust-analyzer is the main rust LSP (Language Server Protocol). So super handy! Here’s their homepage: https://rust-analyzer.github.io/

I wanted to have it running for little all the programs and tests I’d write and run while going through “The Book” and have settled on a setup I thought I’d share.

The main problem I encountered is that having R-A run on a single file isn’t really a thing. It seems it kinda is but I couldn’t get it working and it seemed to be a pain anyway. Plus I wanted to be able to use both cargo projects/crates and little test programs/functions simultaneously from a single workspace in my text editor dedicated to working through The Book.

My solution

at the moment

What I settled on was:

  • Running multiple cargo projects under a single instance of rust-analyzer running in a single workspace in my editor
  • Organising simple test programs as specific functions in a single cargo project.
    • So far, I’m thinking of organising these thematically specifical cargo projects. So I’ve got one called “borrow_checker” for all borrow checker and ownership toy examples.
    • These specific functions can get called from a single main() if helpful/necessary.

EG directory structure:

the_book/
 ├──  Cargo.lock
 ├──  Cargo.toml
 ├──  guessing_game/
 │  ├──  .gitignore
 │  ├──  Cargo.lock
 │  ├──  Cargo.toml
 │  ├──  src/
 │  └──  target/
 ├──  hello_cargo/
 │  ├──  .gitignore
 │  ├──  Cargo.lock
 │  ├──  Cargo.toml
 │  ├──  src/
 │  └──  target/
 ├──  misc_play/
 │  └──  borrow_checker/
 │     ├──  .gitignore
 │     ├──  Cargo.lock
 │     ├──  Cargo.toml
 │     ├──  src/
 │     └──  target/
 └──  target/
    ├──  .rustc_info.json
    ├──  CACHEDIR.TAG
    └──  debug/

Basically everything inside the_book/ is its own cargo project.

And inside misc_play/borrow_checker/src/ is a typical main.rs with multiple functions testing or toying with something I was trying to understand … and hopefully use the LSP to help me with.

Getting this to work

So that’s the structure. But getting it to work requires a little trick. It requires using a Cargo Workspace.

In this case, it’s a matter of adding a Cargo.toml file at the top level (ie, the_book/Cargo.toml) with the following:

[workspace]

resolver = "2"
edition = "2021"

members = [
	"guessing_game",
	"hello_cargo",
	"misc_play/borrow_checker"
]

Here, members is clearly listing each of the projects or libraries. And I added the resolver and edition keys to silence a cargo warning about incompatible resolvers (which I don’t know anything about).

With this file, when at the top level, one can run cargo build to build all of the projects/packages. Or, cargo build -p SPECIFIC_MEMBER to build only a specific project/package. Meanwhile, rust-analyzer seems happy to work on any file from any of these projects in a single editor workspace.

There’s a section in The Book on cargo workspaces: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html (where this feature is about much more than just getting rust-analyzer to work with my preferred directory structure!)


Anyone else have thoughts on how best to structure your code and setup for working through something like The Book or any other materials for that matter?