I want to create a crate with both a library and a binary that provides a cli for the library. Looking at the documentation, it recommends creating files src/lib.rs and src/main.rs. Or, if there are more binaries or a binary has submodules, then it recommends creating the binary root as src/bin/main.rs. The documentation does not explain why though.
When I tried to solve the issue of how to organise the files in such a crate I came up with a different solution. I would create the lib root as src-lib/lib.rs and the binary root as src-bin/main.rs. I designed it like this because this way, the library and the binary cannot accidentally share module files. And to a reader of the code it is immediately clear which modules belong to the binary, and which to the library.
Arguably, having a src/bin/main.rs file also separates binary modules from library modules, but to an uninformed reader it may seem like files in src/bin/ could be submodules of src/lib.rs.
I somehow can't find arguments for putting binary roots and library roots into a common src folder rather than putting them into separate src-bin and src-lib folders. Is there something I am not seeing?
Personally, I agree that having bin and lib sources mixed together in the same directory can lead to errors and confusion. I’ve especially seen a lot of newcomers to Rust get caught up by this.
Why does Cargo look for both files in the same directory by default? I don’t really know, but I guess it does make things easy in some simple cases, like where there is only one target (bin or lib, but not both), or where one or both targets has just a single source file.
It's most likely for convenience for library-only or binary-only crates, which should be most crates. They also share the same build scripts, dependencies, other Cargo.toml settings, and crates.io page when published. And the library is always added as a dependency to the binary. If you want more separation, you can always split it into a workspace.
I now ended up using two separate crates, one for bin and one for lib. Because I realised that also dependencies are hard to separate between binary and lib within a single crate.
My understanding was even a thin binary would be considered a separate crate to its associated library (but perhaps there is another level to this I’m missing?)