<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}]"}