Rust Project Layout



Rust Project Layout Guide
Basic Project Structure
my_project/
|-- Cargo.toml # Project manifest and dependencies
|-- Cargo.lock # Locked dependency versions (auto-generated)
|-- src/ # Source code directory
| |-- main.rs # Entry point for binary crates
| `-- lib.rs # Entry point for library crates
|-- tests/ # Integration tests
|-- benches/ # Benchmarks
|-- examples/ # Example programs
|-- target/ # Build artifacts (gitignored)
`-- README.md # Project documentation
Binary vs Library Projects
Binary Crate (Application)
my_app/
|-- Cargo.toml
`-- src/
|-- main.rs # Required entry point
`-- bin/ # Additional binaries (optional)
`-- other_tool.rs
Library Crate
my_lib/
|-- Cargo.toml
`-- src/
`-- lib.rs # Required entry point
Mixed Binary and Library
my_project/
|-- Cargo.toml
`-- src/
|-- main.rs # Binary entry point
`-- lib.rs # Library entry point
Module Organization
Simple Module Structure
src/
|-- main.rs
|-- config.rs # Single-file module
`-- utils.rs # Single-file module
Nested Module Structure
src/
|-- main.rs
|-- lib.rs
|-- models/ # Module directory
| |-- mod.rs # Module declaration
| |-- user.rs
| `-- post.rs
|-- handlers/
| |-- mod.rs
| |-- auth.rs
| `-- api.rs
`-- utils/
|-- mod.rs
|-- validation.rs
`-- helpers.rs
Common Project Layouts
Web Application (using Actix-web/Rocket)
web_app/
|-- Cargo.toml
|-- .env # Environment variables
|-- migrations/ # Database migrations
|-- static/ # Static assets
| |-- css/
| |-- js/
| `-- images/
|-- templates/ # HTML templates
|-- src/
| |-- main.rs
| |-- lib.rs
| |-- config.rs # Configuration
| |-- db.rs # Database connection
| |-- models/ # Data models
| | |-- mod.rs
| | `-- user.rs
| |-- handlers/ # Request handlers
| | |-- mod.rs
| | `-- users.rs
| |-- middleware/ # Middleware
| | |-- mod.rs
| | `-- auth.rs
| `-- routes.rs # Route definitions
`-- tests/
`-- integration_test.rs
CLI Application
cli_app/
|-- Cargo.toml
|-- src/
| |-- main.rs # Entry point and CLI setup
| |-- cli.rs # CLI argument parsing
| |-- commands/ # Command implementations
| | |-- mod.rs
| | |-- init.rs
| | |-- build.rs
| | `-- run.rs
| |-- config/ # Configuration management
| | |-- mod.rs
| | `-- settings.rs
| `-- utils/
| |-- mod.rs
| `-- helpers.rs
`-- tests/
`-- cli_test.rs
Library with Features
my_library/
|-- Cargo.toml # With feature flags defined
|-- src/
| |-- lib.rs # Main library interface
| |-- core/ # Core functionality
| | |-- mod.rs
| | `-- engine.rs
| |-- features/ # Optional features
| | |-- mod.rs
| | |-- async_support.rs
| | `-- serialization.rs
| `-- prelude.rs # Common re-exports
|-- examples/
| |-- basic.rs
| `-- advanced.rs
|-- benches/
| `-- performance.rs
`-- tests/
|-- unit_tests.rs
`-- integration_tests.rs
Workspace Layout (Multiple Crates)
workspace/
|-- Cargo.toml # Workspace manifest
|-- crates/
| |-- core/ # Core library
| | |-- Cargo.toml
| | `-- src/
| | `-- lib.rs
| |-- cli/ # CLI binary
| | |-- Cargo.toml
| | `-- src/
| | `-- main.rs
| `-- api/ # API server
| |-- Cargo.toml
| `-- src/
| `-- main.rs
|-- shared/ # Shared utilities
| |-- Cargo.toml
| `-- src/
| `-- lib.rs
`-- docs/ # Documentation
Workspace Cargo.toml
[workspace]
members = [
"crates/core",
"crates/cli",
"crates/api",
"shared",
]
[workspace.dependencies]
serde = "1.0"
tokio = "1.0"
Testing Structure
Unit Tests (inline)
// src/calculator.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 2), 4);
}
}
Integration Tests
tests/
|-- common/ # Shared test utilities
| `-- mod.rs
|-- integration_test1.rs
`-- integration_test2.rs
Configuration Files
Essential Configuration
my_project/
|-- .gitignore # Git ignore patterns
|-- .cargo/
| `-- config.toml # Cargo configuration
|-- rust-toolchain.toml # Rust version specification
|-- rustfmt.toml # Code formatting rules
|-- clippy.toml # Linter configuration
|-- .github/
| `-- workflows/
| `-- ci.yml # CI/CD pipeline
`-- .vscode/ # VS Code settings
`-- settings.json
Example .gitignore
# Rust
/target
**/*.rs.bk
*.pdb
Cargo.lock # For libraries
# IDE
.idea/
*.swp
*.swo
.vscode/
*.code-workspace
# OS
.DS_Store
Thumbs.db
# Environment
.env
*.env.local
Example rustfmt.toml
edition = "2021"
max_width = 100
use_small_heuristics = "Max"
imports_granularity = "Crate"
group_imports = "StdExternalCrate"
Documentation Structure
my_project/
|-- README.md # Project overview
|-- CHANGELOG.md # Version history
|-- CONTRIBUTING.md # Contribution guidelines
|-- LICENSE # License file
|-- docs/
| |-- architecture.md
| |-- api.md
| `-- guides/
| |-- getting_started.md
| `-- development.md
`-- src/
`-- lib.rs # Doc comments for API docs
Build Scripts and Assets
my_project/
|-- build.rs # Build script
|-- assets/ # Runtime assets
| |-- config/
| | `-- default.toml
| `-- data/
| `-- init.sql
`-- resources/ # Embedded resources
`-- schema.sql
Example build.rs
use std::env;
use std::fs;
use std::path::Path;
fn main() {
// Copy assets to output directory
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("config.toml");
fs::copy("assets/config/default.toml", dest_path).unwrap();
// Rerun if changed
println!("cargo:rerun-if-changed=assets/");
}
Best Practices
1. Module Organization
- Keep modules focused on a single responsibility
- Use
mod.rs
for module directories - Prefer flat module structures when possible
- Group related functionality together
2. Naming Conventions
- Use snake_case for file and directory names
- Match module names to file names
- Use descriptive names that indicate purpose
3. Separation of Concerns
src/
|-- domain/ # Business logic
|-- application/ # Application services
|-- infrastructure/ # External services
`-- presentation/ # API/CLI layer
4. Feature Flags
[features]
default = ["std"]
std = []
async = ["tokio", "async-trait"]
serde_support = ["serde", "serde_json"]
5. Dependencies Organization
[dependencies]
# Core dependencies
serde = { version = "1.0", features = ["derive"] }
# Optional dependencies
tokio = { version = "1.0", optional = true }
[dev-dependencies]
# Test dependencies
criterion = "0.5"
mockall = "0.11"
[build-dependencies]
# Build script dependencies
cc = "1.0"
Platform-Specific Code
src/
|-- lib.rs
|-- common.rs # Shared code
`-- platform/
|-- mod.rs
|-- unix.rs # Unix-specific
|-- windows.rs # Windows-specific
`-- wasm.rs # WebAssembly-specific
FFI (Foreign Function Interface) Layout
ffi_project/
|-- Cargo.toml
|-- build.rs # Generate bindings
|-- src/
| |-- lib.rs
| |-- ffi.rs # FFI definitions
| `-- wrapper.rs # Safe Rust wrappers
|-- include/ # C headers
| `-- mylib.h
`-- cbindgen.toml # C binding generator config
Macro Projects
macro_lib/
|-- Cargo.toml
|-- src/
| `-- lib.rs # Macro definitions
|-- macro_derive/ # Procedural macros
| |-- Cargo.toml
| `-- src/
| `-- lib.rs
`-- tests/
`-- macro_tests.rs