Package Structure in Rust
A Rust package repersents a complete project managed by Cargo, Rust's build system and package manager. Each package contains one or more crates and is defined by a Cargo.toml manifest file that specifies metadata, dependencies, and build configuration.
[package]
name = "project_analyzer"
version = "1.0.0"
edition = "2021"
[dependencies]
regex = "1.5"
serde_json = "1.0"
A package can contain multiple binary crates organized in the src/bin directory:
project_directory/
├── Cargo.toml
└── src/
├── main.rs # Primary binary crate
└── bin/
├── analyzer.rs # Additional binary
└── reporter.rs # Another binary crate
Crate Compilation Units
A crate serves as Rust's fundamental compilation unit, representing either an executable binary or a reusable library. The compiler processes each crate independently during compilation.
Binary crates contain a main() function as the entry point:
// src/main.rs
fn main() {
println!("Application starting");
process_data();
}
Library crates provide functionality without a main entry point:
// src/lib.rs
pub fn data_processing(input: &str) -> String {
format!("Processed: {}", input)
}
Module System Organization
Modules enable logical code organization within crates, controlling visibility through privacy modifiers and facilitating code separation across files.
// src/main.rs
mod data_utils;
fn main() {
data_utils::process_input("sample data");
}
// src/data_utils.rs
pub fn process_input(input: &str) {
println!("Processing: {}", input);
internal_helper();
}
fn internal_helper() {
// Private function implementation
}
For complex module hierarchies, directroy-based organization is supported:
src/
├── main.rs
└── data_processing/
├── mod.rs # Module declaration file
├── parser.rs # Submodule
└── validator.rs # Additional submodule
// src/data_processing/mod.rs
pub mod parser;
pub mod validator;
pub fn initialize() {
println!("Data processing module ready");
}
// src/data_processing/validator.rs
pub fn validate_input(input: &str) -> bool {
!input.is_empty()
}
Module accessibility follows Rust's privacy rules, where only pub-marked items are externally accesible:
fn main() {
data_processing::initialize();
data_processing::validator::validate_input("test");
// data_processing::parser::parse() - Error if not pub
}