I have a Rust project (it's a Minesweeper game implementation).
The whole functionality of the game itself is written as a library, so that it could be 1) shared as a crate on crates.io and 2) used with different frontends.
At the moment I have 2 frontends: the first one is debug_main
, which is just the most basic textual input/output for the game; the other one is main
which is a TUI written in ratatui.
The current issue is that I don't like the files structure. The biggest problem is that now everything inside the bin
folder is considered a separate executable. So I can run cargo run --bin main
and --bin debug_main
as well as --bin app
and --bin game_ui
, which is not what I want, as there are only 2 executables: main
and debug_main
, and all the other files (app
, event
, game_ui
, menu_ui
, tui
and update
) are the dependencies of main
.
This file structure comes from ratatui: since it's a framework, not just a library, it dictates the file/project structure to stick to (obviously, I understand that I can deviate from it, but not an expert enough to think that "I know better").
So, what they're dictating, is effectively splitting your app into an executable (main
) and the lib (all the other files). But for me (as i understand it) there's a problem that I already have a lib. And, as far as I know, it's impossible to have more than one lib per crate.
What do I do in my case? How can I abstract at least all the files in the bin
folder (except the two executables main
and debug_main
), so that they don't become executables as well? How do I structure my project when it's devided into 1 lib and many binaries, but at the same time binaries themselves may require underlying libs? In general, how do I put things in order in my project? What are the best recoomendations?
For reference, here's the Cargo.toml
file's contents (nothing special about it):
[package]
name = "miners"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.4.18", features = ["derive"] }
color-eyre = "0.6.2"
crossterm = "0.27.0"
rand = "0.8.5"
ratatui = "0.25.0"
Here's what the mod
declarations look like in main.rs
:
mod app;
mod event;
mod game_ui;
mod menu_ui;
mod tui;
mod update;
and in debug_main
use miners::{field::Field, Minesweeper, MinesweeperAction, MinesweeperStatus};
You can either
├── src/
│ ├── lib.rs
│ ├── some_module.rs
│ └── bin/
│ ├── debug/
│ │ ├── main.rs
│ │ └── some_module.rs
│ └── tui/
│ ├── main.rs
│ └── some_module.rs
Each folder or module
under bin
-directory will be a separate executable being build. The name of the executable will be the directory name.