<style> /* basic design */ .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6, .reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p { font-family: 'Meiryo UI', 'Source Sans Pro', Helvetica, sans-serif, 'Helvetica Neue', 'Helvetica', 'Arial', 'Hiragino Sans', 'ヒラギノ角ゴシック', YuGothic, 'Yu Gothic'; text-align: left; line-height: 1.5; letter-spacing: normal; text-shadow: none; word-wrap: break-word; color: #AAA; } .reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {font-weight: bold;} .reveal h1, .reveal h2, .reveal h3 {color: #2980b9;} .reveal th {background: #DDD;} .reveal section img {background:none; border:none; box-shadow:none; max-width: 95%; max-height: 95%;} .reveal blockquote {width: 90%; padding: 0.5vw 3.0vw;} .reveal table {margin: 1.0vw auto;} .reveal code {line-height: 1.2;} .reveal p, .reveal li {padding: 0vw; margin: 0vw;} .reveal .box {margin: -0.5vw 1.5vw 2.0vw -1.5vw; padding: 0.5vw 1.5vw 0.5vw 1.5vw; background: #EEE; border-radius: 1.5vw;} /* table design */ .reveal table {background: #f5f5f5;} .reveal th {background: #444; color: #fff;} .reveal td {position: relative; transition: all 300ms;} .reveal tbody:hover td { color: transparent; text-shadow: 0 0 3px #AAA;} .reveal tbody:hover tr:hover td {color: #444; text-shadow: 0 1px 0 #CCC;} /* blockquote design */ .reveal blockquote { width: 90%; padding: 0.5vw 0 0.5vw 6.0vw; font-style: italic; background: #f5f5f5; } .reveal blockquote:before{ position: absolute; top: 0.1vw; left: 1vw; content: "\f10d"; font-family: FontAwesome; color: #2980b9; font-size: 3.0vw; } /* font size */ .reveal h1 {font-size: 4.0vw;} .reveal h2 {font-size: 3.5vw;} .reveal h3 {font-size: 2.8vw;} .reveal h4 {font-size: 2.6vw;} .reveal h5 {font-size: 2.4vw;} .reveal h6 {font-size: 2.2vw;} .reveal section, .reveal table, .reveal li, .reveal blockquote, .reveal th, .reveal td, .reveal p {font-size: 2.0vw;} .reveal code {font-size: 1.0vw;} /* new color */ .red {color: #EE6557;} .blue {color: #16A6B6;} /* split slide */ #right {left: -18.33%; text-align: left; float: left; width: 50%; z-index: -10;} #left {left: 31.25%; text-align: left; float: left; width: 50%; z-index: -10;} </style> <style> /* specific design */ .reveal h2 { padding: 0 1.5vw; margin: 0.0vw 0 2.0vw -2.0vw; border-left: solid 1.0vw #2980b9; border-bottom: solid 0.6vw #d7d7d7; } </style> <!-- --------------------------------------------------------------------------------------- --> # Rust Study Session \#6 ## Ch. 7: Managing Growing Projects with Packages, Crates, and Modules ### 2020.09.11 - Pravesh K Pradhan --- ## Packages and Crates - crate is a binary or library. - package is one or more crates that provide a set of functionality. - package must contain atleast one crate(binary or library). ---- ### Building a package with cargo ```bash= $ cargo new my-project Created binary (application) `my-project` package $ ls my-project Cargo.toml src $ ls my-project/src main.rs ``` ```bash= my-project ├── Cargo.toml └── src └── main.rs ``` ---- - by default a new package will contain only a single crate - the **scr/main** crate - packages can also contain two crate: - **src/main** and **src/lib** - in this case, a brinary and library. - also called **crate roots** ---- ```bash= package ├── src/main(binary) │ ├── main.rs └── src/lib(library) ├── pgm1.rs ├── pgm2.rs └── pgm3.rs ``` --- ## Defining Modules to Control Scope and Privacy - used to orgnise the code - defined by the keyword **mod** - control **private** or **public** ---- ```bash= $ cargo new --lib restaurant ``` ```bash= restaurant ├── Cargo.toml └── src (library) └── lib.rs ``` Filename: src/lib.rs ```rust= mod front_of_house { mod hosting { fn add_to_waitlist() {} fn seat_at_table() {} } mod serving { fn take_order() {} fn serve_order() {} fn take_payment() {} } } ``` ---- - **mod** tree structure ```bash= crate └── front_of_house ├── hosting │ ├── add_to_waitlist │ └── seat_at_table └── serving ├── take_order ├── serve_order └── take_payment ``` --- ## Paths for Referring to an Item in the Module Tree - absolute path - starts from the crate root - uses the crate name or just "crate" - relative path - starts from the current module - uses **"self"**, **"super"** or an identifier ---- ### Defining Absolute path and Relative path ```rust= mod front_of_house { mod hosting { 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(); } ``` ---- - error msg ```bash= $ cargo build Compiling restaurant v0.1.0 (file:///projects/restaurant) error[E0603]: module `hosting` is private --> src/lib.rs:9:28 | 9 | crate::front_of_house::hosting::add_to_waitlist(); | ^^^^^^^ error[E0603]: module `hosting` is private --> src/lib.rs:12:21 | 12 | front_of_house::hosting::add_to_waitlist(); | ^^^^^^^ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0603`. error: could not compile `restaurant`. To learn more, run the command again with --verbose. ``` ---- ### Exposing Paths with the pub Keyword ```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(); } ``` ---- ### Starting Relative Paths with super ```rust= fn serve_order() {} mod back_of_house { fn fix_incorrect_order() { cook_order(); super::serve_order(); } fn cook_order() {} } ``` ---- ### When to use super - if the code gets moved, fewer place to update the code - module and function stay relative to each other and gets moved together ---- ### Making Structs and Enums Public ```rust= mod back_of_house { pub struct Breakfast { pub toast: String, seasonal_fruit: String, } impl Breakfast { pub fn summer(toast: &str) -> Breakfast { Breakfast { toast: String::from(toast), seasonal_fruit: String::from("peaches"), } } } } pub fn eat_at_restaurant() { // Order a breakfast in the summer with Rye toast let mut meal = back_of_house::Breakfast::summer("Rye"); // Change our mind about what bread we'd like meal.toast = String::from("Wheat"); println!("I'd like {} toast please", meal.toast); // The next line won't compile if we uncomment it; we're not allowed // to see or modify the seasonal fruit that comes with the meal // meal.seasonal_fruit = String::from("blueberries"); } ``` ---- ```rust= mod back_of_house { pub enum Appetizer { Soup, Salad, } } pub fn eat_at_restaurant() { let order1 = back_of_house::Appetizer::Soup; let order2 = back_of_house::Appetizer::Salad; } ``` --- ## Bringing Paths into Scope with the "use" Keyword ```rust= mod front_of_house { pub mod hosting { pub fn add_to_waitlist() {} } } // bringing absolute path in-scope use crate::front_of_house::hosting; // bringing relative path in scope use self::front_of_house::hosting; pub fn eat_at_restaurant() { hosting::add_to_waitlist(); hosting::add_to_waitlist(); hosting::add_to_waitlist(); } ``` ---- ### Idiomatic use Paths ```rust= use std::fmt; use std::io; fn function1() -> fmt::Result { // --snip-- } fn function2() -> io::Result<()> { // --snip-- } ``` ---- ### Providing New Names with the as Keyword ```rust= use std::fmt::Result; use std::io::Result as IoResult; fn function1() -> Result { // --snip-- } fn function2() -> IoResult<()> { // --snip-- } ``` ---- ### Re-exporting Names with pub use - combining "use and "pub ```rust= mod front_of_house { pub mod hosting { pub fn add_to_waitlist() {} } } pub use crate::front_of_house::hosting; pub fn eat_at_restaurant() { hosting::add_to_waitlist(); hosting::add_to_waitlist(); hosting::add_to_waitlist(); } ``` ---- ### Using External Packages - Cargo.toml └── [dependencies] rand = "0.5.5" ```rust= use rand::Rng; fn main() { let secret_number = rand::thread_rng().gen_range(1, 101); } ``` ---- ### Using Nested Paths to Clean Up Large use Lists ```rust= use std::cmp::Ordering; use std::io; ``` ```rust= use std::{cmp::Ordering, io}; ``` ```rust= use std::io; use std::io::Write; ``` ```rust= use std::io::{self, Write}; ``` ---- ### The Glob Operator - defined by "*" - used to bring all public items defined in a path into scope ```rust= use std::collections::*; ``` ※ Glob can make it harder to tell what names are in scope and where a name used in your program was defined. --- ## Separating Modules into Different Files - Filename: src/lib.rs ```rust= mod front_of_house; pub use crate::front_of_house::hosting; pub fn eat_at_restaurant() { hosting::add_to_waitlist(); hosting::add_to_waitlist(); hosting::add_to_waitlist(); } ``` ※ ";" tells Rust to load the contents of the module from another file with the same name as the module ---- - Filename: src/front_of_house.rs ```rust= pub mod hosting { pub fn add_to_waitlist() {} } ``` --- ## Summary - Rust lets you split a package into multiple crates and a crate into modules - by specifying absolute or relative paths - paths can be brought into scope with "use" statement - Module code is private by default - Modules can be made public by using "pub"
{"metaMigratedAt":"2023-06-15T12:37:20.723Z","metaMigratedFrom":"YAML","title":"Rust Ch.7 - Managing Growing Projects with Packages, Crates, and Modules","breaks":true,"description":"Rust Ch.6 - Enums and Pattern Matching","slideOptions":"{\"theme\":\"black\",\"slideNumber\":\"c/t\",\"center\":false,\"transition\":\"fade\",\"keyboard\":true}","contributors":"[{\"id\":\"61a2df68-93cc-49bc-bbd2-d6508763a4ce\",\"add\":9178,\"del\":1931}]"}
    389 views