- Package: Collection of one or more crates with
Cargo.toml - Crate: Compilation unit - either binary (
src/main.rs) or library (src/lib.rs) - Module: Code organization within crates using
modkeyword - Visibility: Use
pubto make items public, private by default - Paths: Absolute (
crate::) or relative (self::) to access modules - Usage:
usekeyword to bring items into scope
- Package is a collection of one or more crates
- Crate is a group of Rust source files that can be compiled into a library or executable
- Binary Crate: An executable program. Must have a
mainfunction. - Library Crate: A reusable library that can be used by other crates.
- Binary Crate: An executable program. Must have a
- Module(
mod) is a way to organize code within a crate, allowing for better structure and visibility control. - Crate Root: The main file of a crate, which is either
src/main.rsfor binary crates orsrc/lib.rsfor library crates. Cargo.tomlis the manifest file for Rust projects, containing metadata about the package, dependencies, and build configuration.
A package can have:
- One or more crates
- Can have more than one binary crate
- Can not have more than one library crate
- A
Cargo.tomlfile
It was hard for me to understand why a package can have multiple binary crates but only one library crate. π€ The conclusion I came to is that package is not just a single executable program but a collection of related crates that can be built or shared.
- Library crate contains core logic and shared functionality. And package is an API that can be used by other packages. Therefore, a package should have only one library crate.
- A single package can have multiple binary crates to provide different entry points or applications that use the shared library crate.
Let's say we are creating "Awesome Video Editor" package.
- Library Crate (
src/lib.rs):- Contains core functionality like video processing, filters, and effects.
- Can be used by other packages or applications.
- Binary Crates
src/main.rs: The main entry point for the application.src/bin/converter.rs: A simple video format converter.src/bin/uploader.rs: A tool to upload videos to a cloud service.
Like this, the package can have multiple binary crates that provide different functionalities, but only one library crate that contains the core logic and shared functionality.
Modules in Rust are used to:
- To organize code into separate namespaces, making it easier to manage and understand.
- To control the visibility of items (functions, structs, etc.) and prevent naming conflicts.
- To create a module in Rust, you use the
modkeyword. - Elements such as functions, structs, and enums can expose items from a module using the
pubkeyword, which makes them public and accessible from outside the module.
// src/lib.rs
mod video {
pub fn process_video() {
// Video processing logic
}
pub fn upload_video() {
// Video uploading logic
}
fn private_helper() {
// This function is private to the module
}
}To use modules in Rust, you need to bring the elements into scope. To do this, we have to specify the path of the elements we want to use.
-
Absolute Path: The full path from the crate root (e.g.,
crate::video::process_video).craterefers to the root of the current crate. (main.rsorlib.rs)
-
Relative Path: The path relative to the current module (e.g.,
self::process_video). -
To use a module, you can:
- Directly refer to it using the
mod_name::item_namesyntax. - Alternatively, you can use the
usekeyword to bring items into scope.
- Directly refer to it using the
Let's say we have a module named video with a function upload_video that we want to use in our main application.
This is the file structure:
src/
βββ main.rs
βββ video.rs
We can create a module in video.rs:
By the way, you can create a module by using
modkeyword or by creating a separate file with the same name as the module.This was bit confusing. But the way I understood it is that: using
modkeyword is more like declaring a module inline, while creating a separate file is like defining the module in its own file.
// src/video.rs
pub fn process_video() {
// Video processing logic
}
pub fn upload_video() {
// Video uploading logic
}
fn private_helper() {
// This function is private to the module
}Now, we can use this module in our main.rs file:
// src/main.rs
mod video;
use crate::video::upload_video;
fn main() {
// Directly refer to the module
crate::video::process_video();
// using `use` to bring the function into scope
upload_video();
}This allows you to call the process_video function from the video module in your main application.