diff --git a/slides/07-managing_growing_projects_with_packages_crates_and_modules.qmd b/slides/07-managing_growing_projects_with_packages_crates_and_modules.qmd index 8bec82b..0ea69a7 100644 --- a/slides/07-managing_growing_projects_with_packages_crates_and_modules.qmd +++ b/slides/07-managing_growing_projects_with_packages_crates_and_modules.qmd @@ -6,26 +6,117 @@ title: "7. Managing Growing Projects with Packages, Crates, and Modules" # Learning objectives ::: nonincremental -- THESE ARE NICE TO HAVE BUT NOT ABSOLUTELY NECESSARY +- Differentiate between packages, crates, and modules. +- Understand and use Rust's module system (`mod`, `pub`, `use`). +- Implement Cargo workspaces for multi-crate projects. +- Apply best practices for managing and organizing Rust projects. ::: ::: notes -- You can add notes on each slide with blocks like this! -- Load a deck in the browser and type "s" to see these notes. +Encourage questions about any points that feel unclear. ::: -# SLIDE SECTION +# Overview of Packages, Crates, and Modules -## SLIDE +## Key Concepts -- DENOTE MAJOR SECTIONS WITH `# TITLE` (eg `# Installation`) -- ADD INDIVIDUAL SLIDES WITH `##` (eg `## rustup on Linux/macOS`) -- KEEP THEM RELATIVELY SLIDE-LIKE; THESE ARE NOTES, NOT THE BOOK ITSELF. +- **Package**: A Cargo feature that lets you build, test and share crates. Defined by a `Cargo.toml` file. +- **Crate**: A tree of modules that produces a library or executable. Rust's compilation unit. + - **Binary crate**: An executable with a `main` function as an entry point. + - **Library crate**: A crate that can be used by other crates. +- **Module**: A way to organize code and control scope and visibility. +- **Paths**: A way of naming an item, such as a struct, function, or module. -## SLIDE +# Creating and Using Packages -# SLIDE SECTION +## Setting Up a Package -## SLIDE +```console +$ cargo new my_project +$ cd my_project +``` -## SLIDE +- Creates a new package with a `Cargo.toml` and a default binary crate. +- Binary crate root: `src/main.rs`. +- To create a library crate, add a `src/lib.rs`. +- An executable crate must have a `main` function as an entry point. +- A library crate can be used by other crates, and does not need a `main` entry point. + +# Working with Modules +## Control Scope and Privacy with Modules +- Check out the backyard example! + +## Accessing Module Items +``` rust +crate::front_of_house::hosting::add_to_waitlist(); +``` +- Use absolute paths starting with crate + +``` rust +front_of_house::hosting::add_to_waitlist(); +``` +- or, use relative paths starting with the module name + +## Controlling Visibility +``` rust +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + crate::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} +``` +- By default, items are private +- Use `pub` to make modules, functions, and fields accessible + +## No private code in R +- In R, everything is public + - Even un-exported functions can be accessed with `:::`. +- In Rust, private items are not accessible outside their module. + +# Using `use` for Convenience +## Simplify Paths +``` rust +use crate::front_of_house::hosting; + +hosting::add_to_waitlist(); +``` +- Use `use` to shorten paths. +- Works within the scope it's defined. + +## Re-exporting with `pub use` +``` rust +pub use crate::front_of_house::hosting; + +hosting::add_to_waitlist(); +``` +- Makes items available for external users. + +# Organizing Modules Across Files +## Splitting Modules +- Define a module in `src/lib.rs`: +``` rust +mod front_of_house; +``` +- Create `src/front_of_house.rs`: +``` rust +pub mod hosting { + pub fn add_to_waitlist() {} +} +``` + +- Nest submodules in `src/front_of_house/hosting.rs`. + +# Summary +- Rust's module system (`mod`, `pub`, `use`) is powerful for organizing code. +- Packages bundle functionality, crates define scope, and modules control visibility. +- Cargo workspaces help manage complex projects with multiple packages. + +Next steps: Practice by creating a workspace with two crates and exploring the module system further! diff --git a/slides/14-more_about_cargo_and_cratesio.qmd b/slides/14-more_about_cargo_and_cratesio.qmd index 68dc393..03d3b83 100644 --- a/slides/14-more_about_cargo_and_cratesio.qmd +++ b/slides/14-more_about_cargo_and_cratesio.qmd @@ -3,29 +3,140 @@ engine: knitr title: "14. More about Cargo and Crates.io" --- -# Learning objectives +# Learning Objectives ::: nonincremental -- THESE ARE NICE TO HAVE BUT NOT ABSOLUTELY NECESSARY +- Learn more about Cargo's advanced features: + - Customizing builds with release profiles. + - Publishing libraries to [crates.io](https://crates.io/). + - Managing multi-crate projects with workspaces. + - Installing binaries using Cargo. + - Extending Cargo with custom commands. ::: -::: notes -- You can add notes on each slide with blocks like this! -- Load a deck in the browser and type "s" to see these notes. -::: +# Customizing Builds with Release Profiles + +## Release Profiles +- **Profiles**: Predefined configurations for building code. + - `dev`: For development (`cargo build`). + - `release`: For production (`cargo build --release`). + +### Configuration in `Cargo.toml` +```toml +[profile.dev] +opt-level = 0 + +[profile.release] +opt-level = 3 +``` +- `opt-level`: Optimization levels (0-3). + - *Development*: Minimize build time. + - *Production*: Maximize runtime performance. + +# Publishing a Crate to Crates.io +## Steps to Publish +1. Create an Account: Sign up at [crates.io](https://crates.io/). +2. Retrieve API Token: Use `cargo login` to store it locally. +3. Add Metadata in `Cargo.toml`: +``` toml +[package] +name = "my_crate" +description = "A brief description" +license = "MIT OR Apache-2.0" +``` +4. Run Publish: `cargo publish`. + +## Important Notes +- Published versions are *permanent*. +- You can "yank" a version to prevent new dependencies but retain existing ones. + +# Writing Documentation for Crates +## Documentation Comments +- Use `///` for documentation comments. +- Supports Markdown formatting. + +## Example +``` rust +/// Adds one to the input number. +/// +/// # Examples +/// +/// ``` +/// let result = my_crate::add_one(1); +/// assert_eq!(result, 2); +/// ``` +pub fn add_one(x: i32) -> i32 { + x + 1 +} +``` + +- Run `cargo doc --open` to generate HTML documentation +- Bonus: Examples in comments are tested with `cargo test` + +# Organizing Large Projects with Workspaces +## What is a Workspace? +- A workspace groups multiple crates. +- Shared: + - `Cargo.lock` (dependency versions). + - `target` directory (build artifacts). + +## Workspace Configuration +``` toml +[workspace] +members = ["crate1", "crate2"] +``` +Benefits: +- Simplifies management of interdependent crates. +- Avoids redundant compilation of dependencies. -# SLIDE SECTION +# Using Workspaces +## Examples Structure +``` scss +my_project/ +├── Cargo.toml (workspace root) +├── crate1/ +│ ├── Cargo.toml +│ └── src/ +├── crate2/ +│ ├── Cargo.toml +│ └── src/ +└── target/ +``` -## SLIDE +## Building and Testing +- Build entire workspace: `cargo build`. +- Test specific crate: `cargo test -p crate1`. -- DENOTE MAJOR SECTIONS WITH `# TITLE` (eg `# Installation`) -- ADD INDIVIDUAL SLIDES WITH `##` (eg `## rustup on Linux/macOS`) -- KEEP THEM RELATIVELY SLIDE-LIKE; THESE ARE NOTES, NOT THE BOOK ITSELF. +# Installing Binaries with Cargo +## Installing Binary Crates +- Use `cargo install`: +``` sh +cargo install ripgrep +``` +- Binaries stored in `~/.cargo/bin` (add to `$PATH`). -## SLIDE +- Run the tool: +``` sh +rg --help +``` -# SLIDE SECTION +# Extending Cargo with Custom Commands +## Custom Commands +- Name binaries as `cargo-`. +- Accessible via `cargo `. -## SLIDE +## Example: +- A binary named `cargo-fancy`: +``` sh +cargo fancy +``` +Benefits: +- Extend Cargo without modifying it. +- Automatically integrates into `cargo --list`. -## SLIDE +# Summary +- Optimize builds using dev and release profiles. +- Publish crates to crates.io (with clear documentation!). +- Manage multi-crate projects with shared dependencies. +- Install and use binaries with cargo install. +- Create custom Cargo commands for specialized workflows.