Introduction
Why Rust
- Advanced mode can unlock all the optimizations you’ll ever need, while easy mode can be as ergonomic as Python
- It makes you a better programmer by making you aware of how your variables are stored in memory
- How to speak Rust • No Boilerplate 📺
- Rust makes you feel like a GENIUS • No Boilerplate 📺
- Rust is easy • The compiler teaches you • No Boilerplate 📺
- Rust for the impatient • No Boilerplate 📺
- What makes Rust different? • No Boilerplate 📺
- Rust: Your code can be PERFECT • No Boilerplate 📺
- Stop writing Rust • In other languages it’s easy to START projects, but in rust, it’s easy to FINISH them • No Boilerplate 📺
- Rust makes cents • Rust saves cloud computing costs (by being extremely CPU and memory efficent) and the engineering time that would otherwise be spent resolving production bugs • No Boilerplate 📺
- Rust is boring • Why Rust’s superior speed and reliability now make it the best language to choose for almost any project, especially backend web development • No Boilerplate 📺
- Rust is not a faster horse • What makes Rust fundamentally different from C, C++ and other languages that came before it • No Boilerplate 📺
- When to choose Rust • Nice walkthrough of Rust’s comparative readability, safety, cloud CPU and memory cost savings, and supportive community • Tim McNamara 📺
- Considering Rust • Jon Gjengset 📺
- Rust is easy… (we make it hard) • Let’s Get Rusty 📺
Learning Rust
- How to learn Rust • Skim The Book, reread slowly and complete the quizzes, read Rust By Example, complete the
rustlings
katas • No Boilerplate 📺 - Easy Rust • Beginner-friendly guide, also available as a video playlist • David MacLeod 📕 📺
- The Rust Programming Language • “The Book”, also available with quizzes • Rust 📕
- Rust by Example • Guide emphasizing interactive code examples • Rust 📕
- rustlings • Learn by fixing compiler errors and making tests pass • Rust 🛠
- Learn Rust with Rustlings • 3 hr video walkthrough • Chris Biscardi 📺
- A half-hour to learn Rust • Amos Wenger 📖
- The Rust Book Playlist • Follows The Book chapter-by-chapter • Let’s Get Rusty 📺
- Rust exercises • Exercism 🧩
- Advent of Code 🧩
- advent-of-code-rust • Template repo for solving Advent of Code puzzles • Felix Spöttel 🛠
- itertools • Extra iterator functions like
sorted()
• Philippe Cholet 🛠️ - nom • Parsing helpers that are much more performant than regexes • rust-bakery 🛠
- What I learned by solving 50 Advent of Code challenges in Rust • Slides here • Luciano Mammino 📺
- How to set up Rust for Advent of Code • Chris Biscardi 📺
- Learning Rust via Advent of Code • Forrest Smith 📺
- I Completed All 8 Advents of Code in One Go: Here Are the Lessons I Learned • Teiva Harsanyi 📖
- believeradvent-of-code/rust • Rickard Natt och Dag 🧑💻
- Rust code katas • Code Wars 🧩
- Write Your First Program with the Rust Language • Pascal Precht 📺
- Tour of Rust • Richard Anaya 📕
- Rust By Practice 📕
- My path to becoming a Rustacean • Prashanth Rao 📖
- Learning Rust the wrong way • Learning feels harder but is more effective when we mix topics and learning modes (read, watch, build, formulate questions, teach) over a long period of time; resist the illusion of mastery that comes from focusing on one topic or learning mode at a time; rustlings, migrating existing projects to Rust, and teaching as you go are good options • Ólafur Waage 📺
Using Rust in Easy Mode
- Features like references, lifetimes and other optimizations are optional!
- Rust can be as easy to use as Python for quick exploration and hacking if you wait to optimize
- At first, explore quickly by using
unwrap()
andclone()
everywhere - Later, optimize for safety by refactoring
unwrap
s to enums to handle potential edge cases - Later, optimize for performance by refactoring
clone
s to use references, lifetimes, etc if measurably necessary (which it likely won’t be) - How to learn Rust • At first, copy and clone everything (Rust is fast enough), pass owned variables in and out of functions, and generally avoid references (and therefore lifetimes and the borrow checker) unless the compiler tells you to use them • No Boilerplate 📺
- Easy Mode Rust • At first, clone everywhere (e.g. clone the thing you’re iterate over), pass owned instances instead of references into functions, wrap function parameters with
Arc<>
if you need to mutate them, avoid implementing traits when possible (try to stick to deriving existing traits), avoid async if sync can possibly suffice, and see how far you can get with just theVec
andHashMap
data structures • Andre Bogus 📕 - From Python to Rust. Should I be worried about Rust’s complexity in the future? • Reddit 💬
- How useful is Rust for quick prototyping++? • Top level
anyhow::Result
, then use ? on all Result instances to send all errors to the top level • Reddit 💬
General
- The Rust Project • Rust hub, maintained by the Rust team • Rust 📚
- Rust Playground • Online Rust REPL (could also use Replit) • Rust 🛠️
- Operators and Symbols Glossary • The Rust Book 📕
- Keywords Glossary • The Rust Book 📕
- The Rust Standard Library • Offical API docs • Rust 📚
- Rust error codes index - Error codes index • An in-depth explanation of each Rust compiler error • Rust 📚
- The Rust Reference • A more detailed and comprehensive version of “The Book” • Rust 📕
- The Complete Rust Programming Reference Guide • Rahul Sharma, Vesa Kaihlavirta, Claus Matzinger 📕
- Comprehensive Rust • Google Android team 📕
- The rustc Book • How to customize the Rust compiler’s behaviour • Rust 📕
- All Rust features explained • • Explains several key features by showing what they look like in the language they originally came from • Let’s Get Rusty 📺
Updates & Roadmap
- Rust 2024 and beyond • Nicholas Matsakis 📺
- Rust Blog
Sources of Rust Content
- Rust • YouTube channel 📺
- Rust conference channels…
- No Boilerplate • YouTube channel 📺
- Jon Gjengset • YouTube channel 📺
- Let’s Get Rusty • YouTube channel 📺
- Chris Biscardi • YouTube channel 📺
New Project
Dev Tools
- Install Rust • Don’t use Homebrew • Rust 📚
- Tools • Officially recommended tools for Rust projects • Rust 📚
- Build your Rust lightsaber • Recommended tools for Rust projects • No Boilerplate 📺
- Rust in Visual Studio Code • Visual Studio Code 📚
- rust-analyzer • Visual Studio Marketplace 🛠️
- CodeLLDB • Debug Rust and other compiled languages • Visual Studio Marketplace 🛠️
- rust.vim • Official Vim configuration for Rust • Rust 🛠
- rustfmt • Official Rust formatter that enforces these style rules • Rust 🛠
- rust-clippy • Official linting helper that catches these common mistakes • Rust 🛠
- awesome-rust • A curated list of Rust code and resources 🛠️
- Develop your Rust application • May want to use scratch image instead • Docker Docs 📚
Project Stack
- Rust: rustfmt, rust-clippy
- CI:
- dtolnay/rust-toolchain • Concise GitHub Action for installing a Rust toolchain 🛠
- Docker Compose: …
- Observability: tracing, Slack
- Database: postgres, sqlx
- Data manipulation: polars
Crates
- Crate List • Unofficial guide to the Rust ecosystem • Blessed.rs 📚
- polars • Manipulate tabular data • Polars 🛠️
- rand • Generate random values 🛠️
- rayon • Iterate in parallel 🛠️
- regex - crates.io: Rust Package Registry
- serde • Serialize and deserialize to/from JSON and other formats 🛠️
- time • Measure and format date and time (see chrono if you need more) 🛠️
Language features
Variables
let type_inferred = 'immutable'
let type_explicit: &str = 'immutable'
let mut will_change = 'mutable'
// Variable names can be "shadowed"
let shadowed = 69 // unusable soon
let shadowed = true // type can change
Functions
// Every crate starts here
fn main() {}
// Arguments can be owned or borrowed
fn owns_input(arg: String) {}
fn borrows_input(arg: &String) {}
fn mutates_input(arg: &mut String) {}
// Functions can be unnamed
fn contains_closures() {
let x = 1
let y = 2
// Both referred to as "closures"
let closure = |z| x + y + z
let anonymous = |z| z + 3
}
- Rust Doesn’t Have Named Arguments. So What? • Matheus Richard 📖
- How to do named function arguments in Rust | Bon • Awesome solution!
- Rust’s Golden Rule • Whenever the body of a function contradicts the function’s signature, the signature takes precedence; the signature is right and the body is wrong • Steve Klabnik 📖
Data Types
- A JavaScript developer’s first step to understanding Rust types • Chris Biscardi 📺
Numbers
u8
u16
u32
u64
u128
represent non-negative whole numbersi8
i16
i32
i64
i128
for representing whole numbers- pointer sized integers -
usize
isize
for representing indexes and sizes of things in memory - floating point -
f32
f64
Collections
Strings
// Create a string
let s: &str = "hello"; // a slice
let s: String = "hello".to_string();
let s: String = String::from("hello");
// Create a slice from a String
let s_ref = &s; // "hello"
let s_slice_full = &s[..]; // "hello"
let s_slice_part = &s[..4]; // "hell"
&str
String
values are stored on the heap- A slice is a reference to a range of
u8
bytes (ascii characters) in aString
or items in aVector
- The range specifies the index of the first character and the index after the last character
- The slice reference points directly to the substring data on the heap
- A slice gains “read” and “own” permissions and removes the original string pointer’s “write” and “own” permissions
- A slice includes a
len
property - One advantage of slices over index-based ranges is that the slice cannot be invalidated while it’s being used
- Useful methods:
- (similar to Vecs, since they are implemented as a
Vec<u8>
) capacity()
• How many bytes are allocatedchars().count()
pop()
• ReturnOption<char>
of last characterretain()
• Same as filter, pass in a closure that takes a character and returns true if it should stayshrink_to_fit()
• Reduce memory allocated
- (similar to Vecs, since they are implemented as a
- Working with strings in Rust • Amos Wenger 📖
- Small strings in Rust • Amos Wenger 📖
- Rust Pizza Slices, Arrays and Strings • Array and string slices • Code to the Moon 📺
- String vs &str in Rust functions • Herman J. Radtke III 📖
- Creating a Rust function that accepts String or &str • Herman J. Radtke III 📖
Vectors
- Vec • Rust Standard Library 📚
- Useful methods:
- dedup • Remove sequential duplicates (sort first to remove all)
- sort
- sort_unstable
// Create an array slice
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];
assert_eq!(slice, &[2, 3]);
Enums
- Enums are custom types that can be one of a set of enumerated values
Option<T>
helps you use the type system to prevent errors- When enum values have data inside them, you can use
match
orif let
to extract and use those values (depending on how many cases you need to handle)- If the function only has an effect in one condition, an
if let
is most idiomatic - If the function needs to return a value for each condition, a
match
is most appropriate
- If the function only has an effect in one condition, an
- Enum variants are public by default
- Enums and Pattern Matching • The Rust Programming Language 📕
- Option • Rust Standard Library 📚
- Either • Rust crate 📦
- Rust’s Most Important Containers 📦 10 Useful Patterns •
Option
andResult
• Code to the Moon 📺 - Replace Dicts with Rust Enums • Herman J. Radtke III 📖
Structs
- Each field of a struct is private unless annotated with
pub
- Using Structs to Structure Related Data • The Rust Programming Language 📕
HashMap
- hashbrown • More performant drop-in replacement for
HashMap
andHashSet
Iterators
Example from Learning Rust via Advent of Code:
let slot = units
.iter()
.filter(|unit| self.is_enemy(u)) // ignore non-enemies
.flat_map(|unit| unit.pos.adjacent_positions(w,h)) // iterate adjacent positions
.filter(|pos| !walls[pos] && !occupied[pos]) // ignore walls or occupied spaces
.min_by_key(|pos| (self.pos - pos).length_sq()); // pick closest slot
- Iterator in std::iter - Rust
- lazy
- Methods:
- collect - transform iterator into a collection; such as a Vec
- count - counts iterations to reach end
- cycle - creats iterator that loops
- enumerate - creates iterator that returns tuple of iteration count and value
- filter - uses closure to yield values
- find - searches for value
- flat_map - map plus flatten
- fold - applies function to produce a single value
- for_each - calls closure for each value
- map - transforms each value into another
- max - returns largest value in iteration
- max_by - returns largest value using provided comparison function
- min_by_key - returns value given a function
- sum - returns sum of iterator values
- Improving Rust code with combinators • Let’s Get Rusty 📺
- Iterating over Option • Let’s Get Rusty 📺
- Rust’s iterators optimize nicely—and contain a footgun • Iterators read like they’re iterating multiple times, but they actually compile down to a single
for
loop that performs one iteration that composes your actions at each step; that’s a huge performance win but can be a subtle bug in cases where you actually need to iterate multiple times • Nicole Tietz 📖
Generics
- Turbo Fish Syntax Explained • Let’s Get Rusty 📺
Smart Pointers
- Cell
- RefCell
- Rc
- Crust of Rust: Smart Pointers and Interior Mutability • Jon Gjengset 📺
Data Modeling
- Rust: No Classes, No Problem • Make invalid states unrepresentable by creating state machines with enums and match statements • No Boilerplate 📺
- Building a space station in Rust • Define your possible states, then the functions for moving between them • No Boilerplate 📺
Control flow
match
- The match Control Flow Construct • The Rust Programming Language 📕
- Combining
match
and enums is useful in many situations:match
against an enum, bind a variable to the data inside, then execute code based on it - Matches are exhaustive: the arms’ patterns must cover all possibilities
- In the case of
Option<T>
, Rust ensures we explicitly handle theNone
case so we don’t assume we have a value that might be empty - The last match case can be a catch-all case for all remaining values (using a named variable like
other
if the value will be used or_
if it won’t be) - Match on a reference to the variable to avoid moving its ownership to the match handlers
if let
- Concise Control Flow with if let • The Rust Programming Language 📕
- Using
if let
means less typing, less indentation, and less boilerplate code; however, you lose the exhaustive checking thatmatch
enforces - Choosing between
match
andif let
depends on whether gaining conciseness is an appropriate trade-off for losing exhaustive checking - Rust Branching - if let, match • Code to the Moon 📺
Error Handling
?
operator- Announcing Rust 1.13 • Rust Blog 📖
- A Simpler Way to See Results • Logan Smith 📖
Ownership
- Ownership is a big deal in Rust!
- It’s a core concept that makes Rust fundamentally different from other languages
- It results in the compiler forcing you to solve more potential errors ahead of time, in exchange for encountering fewer errors at runtime
- For any type
T
, you haveT
,&mut T
and&T
:T
is owned&mut T
is exclusive&T
is shared
- At compile time, Rust will check that you never have these at the same time:
&mut T
and&T
- multiple
&mut T
- It’s fine to have multiple
&T
- This is all Rust needs in order to prove your code does not have any data races (i.e. instances where one part of your code tries to read or update a value that another part of your code has updated or deleted)
- A
Mutex
provides a safe way to mutate (get&mut T
) shared data (via “locks”), but they are slow because they force sequential access to data and disallow concurrency- A
RWLock
allows concurrent reads, but involves taking and releasing read locks, which is fine if you then do a long process; but if you do not much, then taking/releasing the locks will become a bottleneck
- A
- The Rust Survival Guide • A clear, brief intro to Rust’s ownership and borrowing rules • Let’s Get Rusty 📺
- Ownership Recap • The Rust Programming Language 📕
- Ownership Inventory • The Rust Programming Language 📕
- Declarative memory management • Amos Wenger 📖
- Rust Means Never Having to Close a Socket • Yehuda Katz 📖
References
From The Rust Programming Language, Chapter 4.
- References are non-owning pointers
- They are like pointers in other languages, but with additional contracts (restrictions)
- They allow reading and writing data without consuming its ownership
- References are created with borrows (
&
and&mut
) and used with dereferences (*
), often implicitly - Rust’s borrow checker enforces a system of permissions (read, write, own, flow) that ensures references are used safely:
- Creating a reference will transfer (some or all) permissions from the borrowed path to the reference
- Permissions are returned once the reference’s lifetime (usage) has ended
- Data must outlive (not be dropped during the lifetime of) all references that point to it
- If you want to pass around a reference to a value, you have to make sure that the underlying value lives long enough
- Fix: use/return the original path instead of a reference to it (move ownership)
- Fix: use/return a static literal value instead of a value allocated to the heap (if the data will never change)
- Fix: defer borrow-checking to runtime by cloning a reference-counted pointer to the original path (via
Rc::clone
), which will wait to deallocate the data until the lastRc
pointing to it has been dropped (opt into garbage collection) - Fix: shorten the borrower’s lifetime so the data can be safely changed/dropped
- Copying a value without moving its ownership:
- If a value is immutable and does not own heap data, it can be copied without moving its ownership
- If a variable pointing to heap data could be copied without a move, then two variables could think they own the same data, leading to a double-free
- Examples of types that own heap data (and therefore do not implement the
Copy
trait):String
- Examples of types that do not own heap data (and therefore do implement the
Copy
trait):i32
,&String
- The compiler will not allow two mutable references to the same value to exist at the same time
- Dereferencing a heap value tries to take ownership of it, but ownership cannot be taken through a reference (a non-owning pointer)
- The compiler will fail with “cannot move out of…a shared reference” when trying to copy values stored on the heap to avoid two values thinking they own the same data, which would later result in trying to deallocate the same heap memory twice
- Safe options for accessing heap values (options that don’t move ownership):
- Clone the data
- Use an immutable reference
- Unsafe options for accessing heap values (options that would move ownership):
- …
- Rust Demystified 🪄 Simplifying The Toughest Parts • Demonstrating how references and lifetimes work by repeatedly refactoring a short code example • Code to the Moon 📺
- Rust’s Alien Data Types 👽 Box, Rc, Arc • Examples of when using a smart pointer can solve a problem • Code to the Moon 📺
- Rust Interior Mutability - Sneaking By The Borrow Checker • How to work around the limitations of the Rust borrow checker using
Cell
,RefCell
,RwLock
andMutex
• Code to the Moon 📺 - What’s a reference in Rust? • Julia Evans 📖
- Rust pattern: Rooting an Rc handle • Sometimes it is useful to clone the data you are iterating over into a local variable, so that the compiler knows it will not be freed; if the data is immutable, storing that data in an
Rc
orArc
makes that clone cheap (i.e., O(1)) • Baby Steps 📖
Lifetimes
- Crust of Rust: Lifetime Annotations • Jon Gjengset 📺
Concurrency
- Concurrent vs parallel
Threads
- The State of Async Rust: Runtimes • Recommends synchronously threads over async whenever possible • Matthias Endler 📖
- Think Twice Before Using Async Rust | Prime Reacts • Recommends threads instead • ThePrimeagen 📺
- Scoped threads:
- Threads are automatically joined once the scope ends
- std::thread::scope • Rust 📚
- Channels
- A way to share state between threads
- Crust of Rust: Channels • Jon Gjengset 📺
- Speed up your Rust code with Rayon
- Fearless Concurrency with Rust • Aaron Turon 📖
Async
- Avoid in favor of threads unless not possible for some reason
- async runtime
- Responsible for polling top-level
async
blocks until they are complete - Most popular is
tokio
- Annotate
main
with$[tokio::main]
- Annotate
- Responsible for polling top-level
async
/.await
- Allows execution to continue without being blocked by I/O
- Syntax sugar that allows async code to be written the same way as sync code
- Futures
- Similar to JS Promises, except lazy (do nothing until polled by awaiting them)
- Lazy = a when defined, just a recipe for what will happen if called
- Easy to cancel (just stop polling them)
- No runtime cost if never called
- Tasks
- Similar API to threads (to make it easy to switch to/from
thread
vstokio
implementation) task::spawn
- By default, executed in parallel as a thread pool under the hood
- Similar API to threads (to make it easy to switch to/from
- When to use async/.await vs
std
threads?- Avoid doing CPU-intensive work in an
async
function - Async when IO is the blocker and threads when CPU is the blocker?
- std threads vs tokio Runtime • Shows that
tokio
’s default thread pool for future tasks uses far fewer threads than you’d use by manually spinning up one thread per action yourself • Dodgy Coding 📺
- Avoid doing CPU-intensive work in an
- How to make HTTP requests?
- Let’s write async rust from the ground up! • Conrad Ludgate 📺
- Intro to async/.await in Rust • Let’s Get Rusty 📺
- Asynchronous Programming in Rust • Rust 📕
- Getting started with Tokio. The ultimate starter guide to writing async Rust. • Dreams of Code 📺
- Async-await on stable Rust! • Rust Blog 📖
- The What and How of Futures and async/await in Rust • 3 hr video from Nov 2018 • Jon Gjengset 📺
- The Why, What, and How of Pinning in Rust • 3 hr video from Sep 2019 • Jon Gjengset 📺
- Tokio Tutorial • Tokio 📚
Debugging
println!
macrodbg!
macro- Easy Rust 195: Backtraces at runtime • Use
std::env::set_var("RUST_BACKTRACE", "1")
to enable compile time backtraces on panics +std::backtrace::Backtrace::capture()
to capture at specific points (orforce_capture()
to capture regardless of the env var setting) • David MacLeod 📺
Testing
- Rust Tests Itself (kind of!) • No Boilerplate 📺
- How to organize your Rust tests • LogRocket 📖
- Mocking Rust 🤪 and Testing 🧪 • Code to the Moon 📺
Observability
- Are we observable yet? An introduction to Rust telemetry • Luca Palmieri 📖
- tracing crate
- use instead of using log directly 🛠️
- enable log feature in
Cargo.toml
to automatically emit logs whenever events or spans are created - use tracing::span to capture events along with their durations and any relevant metadata (e.g. variable values at the time)
- use tracing::Instrument to attach a spans to a
Future
- use tracing::Subscriber to …
- use tracing_opentelemetry to emit traces in an OpenTelemetry-compatible format (e.g. so they can be ingested by Honeycomb for further analysis)
- Rust • OpenTelemetry 📚
- Getting Started Instrumenting Rust OpenTelemetry 📚
- Collect Metrics, Logs, and Traces from Your Rust Applications with OpenTelemetry • Florian Tieben 📖
- Rust Telemetry Workshop • Mainmatter 🛠️
- Understanding Rust futures by going way too deep • Starts with a nice error handling, logging and tracing setup • Amos Wenger 📖
Modules, Crates, Packages & Workspaces
- Rust lets you split a package into multiple crates and a crate into modules so you can refer to items defined in one module from another module by specifying absolute or relative paths
- Paths can be brought into scope with a
use
statement so you can use a shorter path for multiple uses of the item in that scope - Module code is generally private by default, but you can make definitions public by adding the
pub
keyword - Paths: A way of naming an item, such as a struct, function, or module
- absolute (starting with
crate
) - relative (possibly starting with
super
) use
keyword- shorten paths by defining a shortcut
- for functions, create a shortcut to the parent module so function calls will start with it make it clear the function isn’t locally defined
- for all other types, create a shortcut to the item itself
- naming collisions can be solved either by stopping at the parent module or creating an alias with the
as
keyword
- absolute (starting with
- Modules and use: Let you control the organization, scope, and privacy of paths
mod
keywordpub
keyword- Rust modules vs files • Faster than Lime 📖
- Crates: A tree of modules that produces a library or executable
- Packages: A Cargo feature that lets you build, test, and share crates
- External packages are available at crates.io
- Using them involves two steps: listing them in your package’s Cargo.toml and bringing their items into scope with
use
- Managing Growing Projects with Packages, Crates and Modules • The Rust Programming Language 📕
- Unboxing Rust Crates, Packages, Modules & Workspaces • Code to the Moon 📺
- Rust API Guidelines • How to manage the changes you make to crates you’ve published for others to use • Rust 📕
- Rust Modules - Explained Like I’m 5 • Refactors a single-module crate into a file with multiple modules, then multiple files with one module each • Let’s Get Rusty 📺
Programming Paradigms
Functional
- Rust’s Hidden Purity System • Particularly
const
functions • No Boilerplate 📺 - Rust on Rails • How to write rust code that never crashes by using the
Result
type to implement the railway pattern, which eliminatesnull
return values by enforcing error awareness and handling • No Boilerplate 📺
Object-Oriented
- Class Based OOP vs Traits • Nice examples of how Java OOP code would be translated to Rust’s structs and traits • Let’s Get Rusty 📺
Macros
- Introduction - The Little Book of Rust Macros • Daniel Keep & Lukas Wirth 📕
- Ace Rust Macros ♠️ the declarative kind • Code to the Moon 📺
- Crust of Rust: Declarative Macros • Jon Gjengset 📺
Optimizing
Performance
- The Rust Performance Book • Nicholas Nethercote 📕
- Profiling:
- Cargo includes a benchmarking tool
- criterion - Rust
- flame - crates.io: Rust Package Registry
- flamer - crates.io: Rust Package Registry
- Compile time:
- Stupidly effective ways to optimize Rust compile time • XX Chan 📖
- Are we fast yet (.rs)
Memory Usage
- Vectors - optimization ideas:
- Define maximum capacity up front (if known)
- Use an array instead
Cargo
- Commands:
- cargo init • The Cargo Book 📕
- cargo install • The Cargo Book 📕
- cargo update • The Cargo Book 📕
- cargo check • The Cargo Book 📕
- cargo test • The Cargo Book 📕
- cargo bench • The Cargo Book 📕
- The Cargo Book • A book on Rust’s package manager and build system • Rust 📕
Use Cases
Cross-Platform
- Dioxus:
- Write once, run everywhere: building apps with Dioxus • One codebase, deploy to the web, desktop, mobile, terminal, etc • Jonathan Kelley 📺
- Learn Dioxus • Dioxus docs 📚
- Dioxus 0.5: Signal rewrite, lifetimes removed, CSS hot-reloading, and more! • Dioxus blog 📖
Command Line
- Command-line apps • Overview of why Rust is a good fit, with links to other resources • Rust 📚
- Command Line Book • How to build effective command line applications in Rust • Rust 📚
- Rust Command Line Argument Parsing (A Better Way With Clap) • Automatic parsing and help generation • Code to the Moon 📺
- Should you use StructOpt or Clap for Rust CLIs | Release Radar • How
clap
(which is used bycargo
andripgrep
) makes parsing CLI args much easier • Chris Biscardi 📺 - Ratatui • A Rust crate for building TUIs 🛠
- Rich Terminal Interfaces with Ratatui • Chris Biscardi 📺
- Reading a config file:
- Implementing Config Files for your Rust CLI tool | Rustlang Lets Code! • Chris Biscardi 📺
Bash replacement
- matklad/xshell • Making Rust a better Bash 🛠️
- rust-script • Run Rust files and expressions as scripts without any setup or compilation step 🛠️
- GitHub - matklad/cargo-xtask
- subprocess - crates.io: Rust Package Registry
Web Backend
- Zero To Production In Rust - An Introduction To Backend Development • Luca Palmieri 📕
- Statically Typed APIs with Poem and Rust • Backend web development stack recommendations • No Boilerplate 📺
- Tide is perhaps my favorite Rust web app framework. • Dreams of Code 📺
- Build A Rust Backend (Really FAST Web Services with Actix Web) • Code to the Moon 📺
- Networking - Rust Programming Language • Overview of why Rust is a good fit, with links to other resources • Rust 📚
- reqwest • Rust Standard Library 📚
- Rocket • Simple, fast, type-safe web framework for Rust • Rocket 🛠
- Build Auth Into Your Rust Web Application (OAuth2) • With Yew-Oath2 and Actix Web • Code to the Moon 📺
- Leptos (full-stack framework):
- The Leptos Book • Leptos 📕
- Build A Rust-Powered Journaling App (with Upstash Redis) • Leptos and Redis • Code to the Moon 📺
- Are we web yet? Yes, and it’s freaking fast!
- Working with a database:
- HTML forms, Databases, Integration tests • Use
postgres
via Docker andsqlx
• Luca Palmieri 📖 - SQLx is my favorite PostgreSQL driver to use with Rust. • Dreams of Code 📺
- Rust & SQL Databases (With Diesel) • Code to the Moon 📺
- HTML forms, Databases, Integration tests • Use
Web Frontend
- Rust and WebAssembly Book • How to use Rust to build browser-native libraries through WebAssembly • Rust 📚
- Web Apps with WebAssembly • Overview of why Rust is a good fit, with links to other resources • Rust 📚
- Rust & Wasm • The advantages of using Rust to build web apps that can be deployed anywhere (by transpiling to WASM) • No Boilerplate 📺
- Web-native Rust apps [PART 2] • No Boilerplate 📺
- Yew • React-like framework for building component-based frontends using Rust • Yew 🛠️
- Full Stack Rust Webapp + Docker Image Build • Yew frontend, Artix backend, shared Cargo workspace • Code to the Moon 📺
- Build A Rust Frontend (Really FAST Web Apps with Yew) • Code to the Moon 📺
- Leptos (full-stack framework):
- Build A Full Stack Chatbot in Rust (feat. Leptos & Rustformers) • Code to the Moon 📺
- Dioxus (full-stack framework):
- Rust full stack web frameworks have a bright future • Contrasts Dioxus (React-like) vs Leptos (Solid-like); at first glance, Leptos’ syntax looks more familiar and attractive to me • Code to the Moon 📺
- Modern All Rust Stack - Dioxus, Axum, Warp, SurrealDB • Builds a notes web app with Rust • Code to the Moon 📺
- Zola • Static site generator 🛠
HTTP request
- reqwest:
- Parsing JSON in Rust using serde and reqwest • Uses
tokio
,async
/await
andserde
• Let’s Get Rusty 📺 - Simplify connecting to an API with Rust using reqwest and serde_json • Uses
serde_json
instead ofserde
to demonstrate how to simplify quickly parsing JSON responses without needing to first define astruct
• Tim McNamara 📺 - HTTP requests in Rust - reqwest: Everything you need to know • With
serde
and with/withouttokio
• Monroe Programs 📺
- Parsing JSON in Rust using serde and reqwest • Uses
- ureq:
- How to make an HTTP request with Rust 🦀 Learn Rust Creatively • Tim McNamara 📺
Games
- Bevy
Comparison to Python
- Rust vs Python: Speed and Optimization • Bocksdin Code 📺
Inbox
-
Laurence Tratt: Rust’s Two Kinds of ‘Assert’ Make for Better Code
-
The magic of Rust’s type system - Examples of how to use the type system to validate your data (parse, don’t validate) and transition between states safely (using the typestate pattern) - Let’s Get Rusty
-
teivah/rust-cheatsheet: Rust Language Cheat Sheet • Teiva Harsanyi 📖
-
Parsing JSON in Rust using serde and reqwest - Let’s Get Rusty
-
Intro to async/.await in Rust - Let’s Get Rusty
-
Learn Rust Programming - For Beginners - Programiz
-
Ratatui | Ratatui - A Rust crate for creating TUIs
-
warpy-ai/rustubble: Beautifull components for your terminal.
-
rust-unofficial/awesome-rust: A curated list of Rust code and resources. - Includes lots of Rust projects
-
Untangle your Markdown-based documentation from your Rust source code • You can write doc comments in an external .md file and import them • timClicks 📺
-
My negative views on Rust • Chris Done 📖