While exploring the way to use gRPC in Rust, I found the tonic project, which seems to be the way to do this. The project looks quite nice, but there is a particular issue especially annoying for the newcomers like myself.

The way, the tutorial suggests dealing with generating code from protobuf file is to create a file named build.rs:

fn main() {
    tonic_build::compile_protos("proto/proto.proto")
        .unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
}

and then during cargo build run, the corresponding Rust code will be generated. The problem (at least for me personally) is that the generated files are placed in some obscure location, under the cargo OUT_DIR, which is something like target/debug/build/{module-name}-{random-hash}/out/proto.rs. Not only this is a very non-intuitive place to look for, but, apparently, Intellij IDEA is not able to provide some critical features like autocomplete or jump-to-definition for the generated files, which is a major hassle, if you ask me, especially if you’re just starting with gRPC/protobuf ecosystem in Rust.

Luckily, it’s pretty easy to change the output directory for the generated files. For this, the build.rs should looks something like:

fn main() {
    tonic_build::configure()
        .out_dir("src/proto/")
        .compile(&["proto/proto.proto"], &["/proto/"]).unwrap();
}

where the .out_dir("src/proto/") sets the target directory for the generated files, &["proto/proto.proto"] defines the path to the proto file, and &["/proto/"] defines an optional list of directories to recursively watch for changes to know when to re-generate the Rust files.

With that, IDEA is happy to do its job and I can easily explore the generated code!