Idiomatic code file layout

Hi there - I'm just wondering - do you tend to have a few files with multiple modules in a single file, or many little files with a struct/trait per file, or somewhere in the middle?

I tend to have a few large files, but navigation can get busy, so I'm wondering more about a Java like layout, with nested directories and very small single focused files.

Throw your opinions my way :wink:

Generally I keep each module in a separate file.
An exception to this is unit test modules.

Since the module is the unit rather than other items, there can be any number of such other items (eg fns, types, macros) within a module as long as they are complementary pieces of the functionality delivered by the containing module.

4 Likes

I tend to find that Rust has more highly-related types than I get in other languages like Java. Coupled with the fact that that module is the privacy boundary, not the class, that means that lots-of-little-files comes out more annoying than helpful to me.

Putting a type and its builder and its iterators in different files, for example, just forces you to do a bunch of tedious module management that often doesn't seem to really help, so I'll just put them in the same one most of the time.

Different user-visible modules are generally better as separate files, though -- the things in them probably shouldn't be highly related, because if they were then maybe they should be in the same module :wink: Sometimes it can be worth non-pub internal implementation detail modules in the same file, though.

4 Likes

In the middle -- a module per logical role or task or object, which may involve multiple data structures (supporting enums, error types, iterator types, builder types, et cetera), and/or traits, and specific or blanket implementations for both.

2 Likes

To reinforce the comments of others: one type per module is more annoying than helpful in my view as well. Rust is not object-oriented, there is no point in disallowing multiple types in a module or file. Put in one place what is related. Of course, on the other end of the spectrum, you shouldn't just create a gigantic lib.rs with every module inline, either. Breaking things up into modules does help navigation of code (and generated docs).

1 Like

I never or almost never put multiple modules in one file, because that means using mod { ... } blocks, which means sacrificing four columns of horizontal space unnecessarily. :wink: (I don't know whether this remains true, but there was a sentiment that Rust source code suffers much "rightward drift" that quickly exhausts horizontal space. ...Now that I think about it, though, that may have been all before the adoption of our modern "block" indentation style, which tends to require less indentation than the old style.)

1 Like

Thanks all - this pretty much confirms my intuition.