Style: Decide between `foo.rs` and `foo/mod.rs`
Problem you are trying to solve
It's time to decide between
foo.rsandfoo/mod.rs. (I'm slightly inclined towardsfoo.rs.) by @rami3l in https://github.com/rust-lang/rustup/pull/3882#issue-2356320731
I still find [
foo.rsimposing] non-trivial cognitive overhead because it means each module appears twice in the directory tree, and I have to decide which one I need to open. by @djc in https://github.com/rust-lang/rustup/pull/3882#issuecomment-2172312913
Happy for us to have a discussion then about what style the project should take, but I've found the opposite - foo.rs means the module file path is always the same, whether or not the module has child modules, or is a leaf itself where a directory with just the module file would be tedious. by @rbtcollins in https://github.com/rust-lang/rustup/pull/3764#issuecomment-2048428811
Solution you'd like
Unify the style of source file organization across the codebase to either one of them, completely eliminating the trace of the other.
Notes
No response
I can no longer find my previous comment on this issue, but I'll try to pull it out again from my memory:
There's nothing inherently wrong about either approach as long as they are used consistently across a codebase. The underlying problem is how one navigates through the filesystem in their IDE of choice.
For example, I use path searching (meaning searching for the path of a specific file) in both VSCode and Neovim, and so foo/bar.rs appears naturally alongside foo.rs, and that's why I'm "slightly inclined towards foo.rs".
However, if you use a tree view in your IDE (I believe most VSCode users do), there's a high possibility that the tree view will put foo/bar.rs in the upper section of the view next to the folder named foo, and foo.rs is located in the lower section of the same view: there's seemingly no visual connection between the two.
Hi @rami3l !
I decided to use foo.rs because I saw a picture on the Internet, which differed the two methods:
Maybe you can take the contents written in this picture into your considerations! :D
As for your concerns about IDEs, my view is that though the RustRover (which I am using) had been stabilized, there are also plenty of developers who are still using VSCode and Neovim, so I'll still lean towards foo.rs despite the picture factor showed above.
@InfyniteHeap What is your experience with RustRover? Is the tree view aware that foo.rs is logically related to foo/bar.rs, or you suffer from the same issue as most VSCode users?
@InfyniteHeap What is your experience with RustRover? Is the tree view aware that
foo.rsis logically related tofoo/bar.rs, or you suffer from the same issue as most VSCode users?
RustRover doesn't put foo.rs and foo/bar.rs together to make them visually related, but I don't think this could confuse me, because I have been touching such this form of tree view when I first started coding by using VSCode.
As for the "path searching" that what you mentioned, I don't know whether RustRover supports this, because I haven't used RustRover for a long time yet. I use VSCode frequently on the contrary. Even though, I almost never used path searching in VSCode😂.
So, I prefer using foo.rs just because I adopted the suggestions mentioned by that picture above. It's no matter for me that the foo.rs and the foo/bar.rs doesn't be visually put together. XD
I have a strong preference for foo.rs
I have a strong preference for foo.rs
I feel like stating this without any rationale isn't very helpful to the discussion.
So, I prefer using
foo.rsjust because I adopted the suggestions mentioned by that picture above. It's no matter for me that thefoo.rsand thefoo/bar.rsdoesn't be visually put together. XD
The picture just says that it's newer -- not that it's better... I think it ended up being not as good in practice as people thought when it was designed.
I put some polls up on social media last night:
- https://hachyderm.io/@djc/112632662452873619
- https://twitter.com/djco/status/1802744430215979385
These have so far gotten 113 responses, which is not a huge sample of course but also big enough to be meaningful IMO.
- 31 (Mastodon) + 27 (Twitter) = 58 people voted for
foo/mod.rs - 25 (Mastodon) + 14 (Twitter) = 39 people voted for
foo.rs - 3 (Mastodon) + 13 (Twitter) = 16 people voted for "see the results" (presumably "no opinion")
Not sure what to make of the split between Mastodon and Twitter results...
So, I prefer using
foo.rsjust because I adopted the suggestions mentioned by that picture above. It's no matter for me that thefoo.rsand thefoo/bar.rsdoesn't be visually put together. XDThe picture just says that it's newer -- not that it's better... I think it ended up being not as good in practice as people thought when it was designed.
I put some polls up on social media last night:
- https://hachyderm.io/@djc/112632662452873619
- https://twitter.com/djco/status/1802744430215979385
These have so far gotten 113 responses, which is not a huge sample of course but also big enough to be meaningful IMO.
- 31 (Mastodon) + 27 (Twitter) = 58 people voted for
foo/mod.rs- 25 (Mastodon) + 14 (Twitter) = 39 people voted for
foo.rs- 3 (Mastodon) + 13 (Twitter) = 16 people voted for "see the results" (presumably "no opinion")
Not sure what to make of the split between Mastodon and Twitter results...
I referred The Tao of Rust and found that this mod.rs-omitting method was initially introduced in Rust 2018. I think there might have some reasons to introduce such this new method, or it would had been removed.
This example is adapted from the corresponding example came from The Tao of Rust.
Assuming there have a file structure like this:
├─src
│ ├─main.rs
│ └─mod_one
│ ├─mod.rs
│ ├─source_file_one.rs
│ └─source_file_two.rs
main.rs calls functions in source_file_one.rs and source_file_two.rs, while source_file_one.rs also uses source_file_two.rs. This method cannot reflect such this hierarchy. When using the new method, it looks like this:
├─src
│ ├─main.rs
│ ├─source_file_one
│ │ └─source_file_two.rs
│ └─source_file_one.rs
Now devs can obviously know the relationship bewtween source_file_one.rs and source_file_two.rs.
That's one of the reason that what I guessed why Rust introduce the new method.
For example, I use path searching (meaning searching for the path of a specific file) in both VSCode and Neovim, and so
foo/bar.rsappears naturally alongsidefoo.rs, and that's why I'm "slightly inclined towardsfoo.rs".
Just to add a bit of personal experience: if the repo I'm dealing with has foo/mod.rs then it's either foobar or foobarmod that I have to type if I want to enter some foo::bar (so either foo/bar.rs or foo/bar/mod.rs). Compared to a 100% certain foo/bar.rs it's not good, but I can stand it...
Assuming there have a file structure like this:
├─src │ ├─main.rs │ └─mod_one │ ├─mod.rs │ ├─source_file_one.rs │ └─source_file_two.rs
main.rscalls functions insource_file_one.rsandsource_file_two.rs, whilesource_file_one.rsalso usessource_file_two.rs. This method cannot reflect such this hierarchy.
For the sake of comparison, wouldn't mod.rs way of hierarchy instead be:
├─src
│ ├─main.rs
│ └─mod_one
│ ├─mod.rs
│ └─source_file_one
│ ├─mod.rs
│ └─source_file_two.rs
So relationship between them is still obvious.
We just need to be consistent. If we follow the mod.rs way, any module source_one that contains modules under it should follow same source_one/mod.rs hierarchy instead of source_one.rs.
Leaf nodes don't need to have mod.rs as they don't have any modules under them.
Not saying new way is bad. But both way makes things obvious if one is consistent.