Setup

1️⃣ IDE and tools

  • Rust in Visual Studio Code
  • Install extra tools.
    cargo install cargo-edit    # 👈 = cargo add.
    cargo install cargo-watch   # 👈 = cargo watch.
    cargo install cargo-audit   # 👈 = cargo audit.
    

2️⃣ Use Cargo

💡 📦 CargoNPM = Package Manager.

cargo init foo           # 👈 Will init app name `foo`.

cargo run                # 👈 Build and Run.
cargo watch              # 👈 Watch for file change and rebuild.
cargo test               # 👈 Test the tests if has.

cargo build --release    # 👈 No debug = Smaller/Faster.

cargo add tokio          # 👈 add package named `tokio`
cargo rm tokio           # 👈 remove package named `tokio`.

💡 tokio crate make async easier.

3️⃣ Hello World

👩🏻‍💻 enter cargo init hello-world via command line.

📂 hello-world
├─ 📂 src           # 👈 keep source code in here.
│  └─ 📄 main.rs    # 👈 app entrypoint.
└─ 📦 Cargo.toml

└─ 📄 main.rs

// 👇 main function as an entrypoint.
fn main() {
  // 👇 macro to print something out.
  println!("hello world!"); // 👈 end with ; suffix.
}

└─ 📦 Cargo.toml

[package]
name = "foo"         # 👈 App name.
version = "0.1.0"    # 👈 App version.
edition = "2021"     # 👈 Rust edition.

[dependencies]
tokio = "1.21.2"     # 👈 Added by `cargo add tokio`.

⚡️ You can now skip to 👉 enjoy coding or continue reading 4️⃣ below. 👇


4️⃣ Modules and Project structure.

🤔 What if main.rs has to many codes? Your should separate that concern to each file/folder.

🗂 App + File Module

Separate some function to each file.
📂 foo
├─ 📂 src
│  ├─ 📄 utils.rs    # 👈 module as a file.
│  └─ 📄 main.rs     # 👈 will need utils file.
└─ 📦 Cargo.toml

│ ├─ 📄 utils.rs

#![allow(unused)]
fn main() {
pub fn hello() {    // 👈 make it public, or just pub(crate) for internal use.
  println!("hello world!");
}
}

│ └─ 📄 main.rs

mod utils;          // 👈 include utils file.
use utils;          // 👈 and use it.

fn main () {
  utils::hello();    // 👈 call hello function.
}

Now you have too many files and want to group it into folder as a module. See below how to👇

🗂 App + Folder Module

Group related files to each folder.

See setup4 example

📂 foo
├─ 📂 src
│  │
│  ├─ 📂 utils
│  │  ├─ 📄 mod.rs     # 👈 entrypoint (similar to index.js in JS).
│  │  ├─ 📄 say.rs     # 👈 Contain hello function.
│  │  └─ 📄 cast.rs    # 👈 will able to use say.
│  │
│  └─ 📄 main.rs       # 👈 `mod utils;` then `use utils::say;`
│
└─ 📦 Cargo.toml

│ │ ├─ 📄 mod.rs

#![allow(unused)]
fn main() {
pub mod say;        // 👈 import "say" and export.

// 👇 It's look like this in JS.
// export * from say;
}

│ │ ├─ 📄 say.rs

#![allow(unused)]
fn main() {
pub fn hello() {    // 👈 make it public, or just pub(crate) for internal use.
  println!("hello world!");
}
}

│ │ └─ 📄 cast.rs

#![allow(unused)]
fn main() {
use super::say      // 👈 just use. (no mod need because of super)

pub fn cast() {
  say::hello();      // 👈 then call hello function.
}
}

│ └─ 📄 main.rs

mod utils;          // 👈 include utils file.
use utils::say;     // 👈 and use.

fn main() {
  say::hello();      // 👈 then call hello function.
}

This is better but now you want to reuse that module with other project. Let's make a library then 👇

🗂 Lib

Separate each lib as crate.
cargo init bar --lib
🗂 utils
├─ 📂 src
│  └─ 📄 lib.rs     # 👈 lib entrypoint.
└─ 📦 Cargo.toml

│ └─ 📄 lib.rs

#![allow(unused)]
fn main() {
pub fn hello() {    // 👈  make it pub so other can use.
    println!("hello world!");
}
}

🤔 Now you have 3 options to use it.

  • Push to github and use it like this in Cargo.toml.

    [dependencies]
    foo = { git="https://YOU_GITHUB_REPO_URL"}
    
  • Publish it to the internet and cargo add foo to use it.

  • Use it in Workspace which is the next topic below.👇

🗂 Workspace

aka Monorepo.
📂 workspace-example
│
├─ 🗂 utils
│  ├─ 📂 src
│  │  └─ 📄 lib.rs     # 👈 lib entrypoint.
│  └─ 📦 Cargo.toml    # 1️⃣ utils's cargo.
│
├─ 📂 foo
│  ├─ 📂 src
│  │  └─ 📄 main.rs    # 👈 app entrypoint.
│  └─ 📦 Cargo.toml    # 2️⃣ foo's cargo.
│
└─ 📦 Cargo.toml       # 3️⃣ Workspace's cargo.

│ └─ 📦 Cargo.toml

[dependencies]
foo = { path="../utils" }  # 👈 2️⃣ foo's cargo. refer to utils via path

└─ 📦 Cargo.toml

# 👇 3️⃣ Workspace's cargo.
[workspace]
members = [
  "utils",
  "foo",
]

Next

Let's continue to Enjoy ➠