Best practices around organising code bases?

So this is more of a question that will lead to subjective/opinionated answers, but I believe there will be some value in getting what the opinion is out there.

So the problem is the fact that I am finding it a bit laborious to quickly get the lay of the land of a new rust code base.

With my background, being with Java, things are a bit simpler and easier...because in Java, 99.99% of the time, a Java file either maps one on one with a class or an interface. This simplicity makes it easier to quickly identify the main components of a code base.

But with Rust, a single file can contain multiple structs/enums/traits even multiple module definitions and with multiple implementations chopped up in the same file or even spread across multiple files.

For example looking at a struct definition, it becomes hard to quickly see the full range of things it can do based on it's implementation and trait implementations because you can have multiple of them in the same file or in multiple files.

So question is; what are the generally accepted best practices in organizing rust code base to make it less cognitive tasking to quickly get the lay of the land?

Do you have any convention you use that makes this easier?

Do you have any tooling (perhaps IDE/code editor feature) that helps with this?

I don't think the currently accepted practice focuses on intra-file discoverability, and that's for the better. Idiomatic Rust code is organized according to functionality/features, rather than being grouped by low-level implementation details (such as whether a particular item happens to be a struct, an enum, or a trait). This gives a much more logical high-level view of the code.

cargo doc --open. This will open the generated documentation, which automatically includes pretty links to all traits a type implements (as well as foreign impls of a local trait). This is likely the low-level view of the code base you are looking for. I also often just ripgrep the code for the name of a particular item if I'm interested in its role across the project.

3 Likes

Rust offers you modules for organizing code within a single crate, and workspaces, to split code into multiple crates (libraries).

  • If your project is large, and there are parts that are easy to split out, use separate crates for them. The rule there could be: if this is split out as a library, is it useful without rest of the project? Or is this functionality self-contained and changed less frequently than the rest of the code?

  • Within the project you can split code into modules. How you do this is entirely up to you. Do whatever makes sense to you. Note that Rust supports re-exports: pub use crate::some_module::whatever::item, so the public API your library presents to the outside world can be different than your module structure. In my experience nested modules are useful for library developer, but a flattened public API is usually more convenient for library users.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.