Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust 1.99 Standard Library Tutorial Curriculum

Toolchain: Rust 1.99 (MSRV; compiler 1.99.0), edition 2024. Format: Each tutorial is designed as a lecture of 15 minutes (hard cap: 30 minutes). If a subject cannot fit under the cap, split it into multiple tutorials and renumber — there is no limit on tutorial count, only on per-tutorial duration. Tutorials are grouped by domain — a thematic area that crosses module boundaries, connecting related types, traits, functions, and macros by use case rather than by where they live in the std hierarchy.


Prologue — The Prelude and Implicit Imports

P.1 · What does the Prelude Import and Why?

What's covered?

  • Edition-dependent preludes: v1 (2015/2018), rust_2021, rust_2024.
  • What changed in 2021 (added TryFrom, TryInto, FromIterator).
  • What changed in 2024 (added Future, IntoFuture).
  • The prelude traits that for loops, the ? operator, collect, and .await use, and the names that need no explicit import.
  • Why understanding the prelude prevents "where does this trait come from?" confusion.

Learn this before Domain 1 if you have ever wondered why certain traits seem to appear from nowhere.

Library Components:

  • std::prelude::v1
  • std::prelude::rust_2021
  • std::prelude::rust_2024

Domain 1 — Ownership Mechanics in the Standard Library

1.1 · Clone, Copy, and Drop: The Lifecycle Trio

What's covered?

  • How Clone, Copy, and Drop interact.
  • When the compiler inserts implicit copies vs. when you must clone explicitly.
  • The relationship between Copy and Drop (mutual exclusion).
  • Shallow vs. deep cloning with clone_from.
  • Performance implications of Clone on collection types.

Library Components:

  • std::clone::Clone
  • std::marker::Copy
  • std::ops::Drop
  • clone_from

1.2 · Borrow, ToOwned, and Cow: Flexible Ownership Boundaries

What's covered?

  • The Borrow and BorrowMut traits as abstraction over ownership.
  • ToOwned for going from borrowed to owned.
  • Cow<'a, B> (clone-on-write) as the bridge that defers allocation.
  • Real use case: building APIs that accept both &str and String without forcing the caller to allocate.

Library Components:

  • std::borrow::Borrow
  • std::borrow::BorrowMut
  • std::borrow::ToOwned
  • std::borrow::Cow

1.3 · AsRef, AsMut, Into, From: The Conversion Matrix

What's covered?

  • When to use AsRef<T> vs. Borrow<T>.
  • The blanket implementations that make From/Into work.
  • TryFrom/TryInto for fallible conversions — including numeric range checks, impl TryFrom<char> for usize (stabilized in 1.94), and impl TryFrom<{integer}> for bool (stabilized in 1.95).
  • as casting behavior (truncation, sign extension) and when try_into() is safer.
  • Infallible as the error type for conversions that cannot fail and its relationship to the never type !.
  • convert::identity as a typed no-op useful in higher-order functions.
  • Designing public APIs with conversion traits to maximize ergonomics.

Library Components:

  • std::convert::AsRef
  • std::convert::AsMut
  • std::convert::From
  • std::convert::Into
  • std::convert::TryFrom
  • std::convert::TryInto
  • std::convert::Infallible
  • std::convert::identity

Domain 2 — Error Handling Ecosystem

2.1 · Result and Option: Beyond the Basics

What's covered?

  • The full combinator API on Result and Option — and_then, or_else, map_or, unwrap_or_default, transpose, flatten, inspect, zip, unzip.
  • Chaining results with ?.
  • The FromResidual trait behind ?.
  • When Option is more appropriate than Result and vice versa.
  • bool::ok_or / ok_or_else (stabilized in 1.98) for turning a predicate into Result<(), E>.

Library Components:

  • std::option::Option
  • std::result::Result

2.2 · The Error Trait and Error Propagation Patterns

What's covered?

  • Implementing std::error::Error.
  • The source() chain for error causes.
  • Display vs. Debug for error formatting.
  • Downcasting errors with downcast_ref.
  • Building custom error hierarchies without third-party crates.
  • The deprecated description() method and why it was superseded.
  • Error::provide for supplying typed context including backtraces (see 2.4 for backtrace capture mechanics).

Library Components:

  • std::error::Error
  • std::fmt::Display
  • std::fmt::Debug
  • <dyn Error>::downcast_ref / downcast_mut / Box<dyn Error>::downcast (inherent methods; the same TypeId technique as std::any::Any)

2.3 · Panic Infrastructure: Hooks, Unwind, and Abort

What's covered?

  • panic!, catch_unwind, resume_unwind, set_hook, take_hook.
  • PanicHookInfo (added in 1.81; the old name PanicInfo is deprecated since 1.82).
  • The difference between std::panic::PanicHookInfo and core::panic::PanicInfo.
  • UnwindSafe and RefUnwindSafe marker traits; AssertUnwindSafe and its From<T> constructor (stabilized in 1.96).
  • When catch_unwind is appropriate (FFI boundaries, thread pools).

Library Components:

  • std::panic
  • std::panic::catch_unwind
  • std::panic::set_hook
  • std::panic::PanicHookInfo
  • std::panic::UnwindSafe
  • std::panic::RefUnwindSafe
  • std::panic::AssertUnwindSafe

2.4 · Backtraces: Capturing Stack Traces

What's covered?

  • Backtrace::capture and Backtrace::force_capture.
  • The RUST_BACKTRACE environment variable.
  • BacktraceStatus — Unsupported, Disabled, Captured.
  • Embedding backtraces in custom error types via Error::provide.
  • When backtraces help (production debugging) and when they hurt (performance).
  • How this integrates with the source() chain from 2.2.

Library Components:

  • std::backtrace::Backtrace
  • std::backtrace::BacktraceStatus

Domain 3 — Strings and Text Processing

3.1 · String, &str, and the UTF-8 Contract

What's covered?

  • Internal representation of String and &str.
  • Why indexing by usize doesn't work.
  • char_indices, chars, bytes.
  • String slicing and the panic on non-boundary indices.
  • str::substr_range (1.98) to recover a substring's byte range by pointer arithmetic.
  • String::from_utf8 vs. from_utf8_unchecked.
  • as_bytes, into_bytes, from_utf8_lossy.
  • String::from_utf8_lossy_owned and FromUtf8Error::into_utf8_lossy (1.99) for lossy conversion of an owned Vec<u8> without a copy of valid input.
  • String::from_utf16le / from_utf16be and their lossy siblings (1.98) for decoding endian-tagged UTF-16 byte streams.

Library Components:

  • std::string::String
  • primitive str
  • std::str::from_utf8
  • std::str::Utf8Error
  • FromUtf8Error

3.2 · Formatting Mastery: fmt, write!, format_args!

What's covered?

  • The fmt module architecture — Display, Debug, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp, Pointer.
  • The Formatter struct and its options (padding, alignment, precision, sign, fill).
  • format_args! as a zero-allocation formatting primitive.
  • {integer}::format_into with NumBuffer (1.98; re-exported from std::fmt since 1.99) for allocation-free decimal integer formatting.
  • Writing custom Display and Debug implementations.
  • DebugStruct, DebugTuple, DebugList, DebugMap, DebugSet builder helpers.

fmt::Write (for formatting to strings/buffers) and io::Write (for byte streams) are distinct traits — write! and writeln! work with both via separate blanket implementations; see 8.1 for the io::Write side.

Library Components:

  • std::fmt
  • std::fmt::NumBuffer
  • all formatting traits
  • std::fmt::Formatter
  • std::fmt::Arguments
  • write!
  • writeln!
  • format!
  • format_args!

3.3 · Pattern Matching on Strings and FromStr Parsing

What's covered?

  • The Pattern trait and what can be used as a string pattern (char, &str, &[char], closures).
  • Methods that use patterns: contains, starts_with, find, rfind, split, splitn, trim_matches, strip_prefix, strip_suffix, strip_circumfix (1.98 — prefix and suffix in one call).
  • FromStr for parsing arbitrary types from strings.
  • str::parse::<T>() ergonomics.

Library Components:

  • std::str::pattern::Pattern
  • std::str::FromStr
  • str methods

3.4 · OsString, CStr, CString: Non-UTF-8 String Types

What's covered?

  • Why OsStr/OsString exist (platform-dependent encoding).
  • Converting between OsStr, Path, str.
  • CStr and CString for C interop — null termination guarantees, as_ptr, from_ptr.
  • Comparison traits between CStr, CString, and Cow<CStr> (stabilized recently).
  • When to use each string type.

Library Components:

  • std::ffi::OsStr
  • std::ffi::OsString
  • std::ffi::CStr
  • std::ffi::CString
  • std::ffi::NulError
  • std::ffi::FromBytesWithNulError

3.5 · ASCII Operations and Character Classification

What's covered?

  • The std::ascii module.
  • char methods for classification (is_alphabetic, is_numeric, is_ascii_*, is_uppercase, etc.).
  • Case conversion with to_lowercase, to_uppercase (iterator-based because of Unicode).
  • make_ascii_lowercase, make_ascii_uppercase on [u8] and str.
  • EscapeDefault, EscapeDebug, EscapeUnicode iterators.

Library Components:

  • std::ascii
  • std::char
  • primitive char methods
  • char::from_digit
  • char::to_digit

Domain 4 — Collections Deep Dive

4.1 · Vec<T>: The Workhorse Collection

What's covered?

  • Internal layout (pointer, length, capacity).
  • Growth strategy.
  • with_capacity, reserve, shrink_to_fit, shrink_to.
  • retain, dedup, dedup_by, dedup_by_key.
  • drain, splice, split_off.
  • push_mut and insert_mut for getting &mut T to the just-inserted element (stabilized in 1.95).
  • into_boxed_slice.
  • into_parts and from_parts (1.99) to decompose a Vec into (NonNull<T>, length, capacity) and rebuild it.
  • Vec as a Deref<Target = [T]> — the slice method inheritance.
  • extend_from_slice vs. extend.

Library Components:

  • std::vec::Vec
  • std::vec::IntoIter
  • std::vec::Drain
  • std::vec::Splice

4.2 · HashMap and HashSet: Hashing Internals and Custom Hashers

What's covered?

  • SwissTable-based implementation (quadratic probing + SIMD lookup).
  • The Entry API (or_insert, or_insert_with, and_modify, or_default).
  • RandomState and BuildHasher.
  • Providing custom hashers.
  • The Hash trait and implementing it correctly (the hash/eq contract).
  • HashSet as HashMap<K, ()> — when sets beat maps.
  • For in-depth coverage of implementing custom Hasher state machines and BuildHasher, see 13.2.

Library Components:

  • std::collections::HashMap
  • std::collections::HashSet
  • std::collections::hash_map::Entry
  • std::hash::Hash
  • std::hash::Hasher
  • std::hash::BuildHasher
  • std::hash::RandomState

4.3 · BTreeMap, BTreeSet, and Ordered Collections

What's covered?

  • B-Tree vs. hash-based collections — when ordering matters.
  • range, split_off, append.
  • The Ord contract for keys.
  • Performance characteristics (O(log n) vs. O(1) amortized).
  • BTreeMap::entry.
  • Iterating in sorted order.
  • Use cases: interval queries, leaderboards, ordered deduplication.

Library Components:

  • std::collections::BTreeMap
  • std::collections::BTreeSet
  • std::collections::btree_map::Entry

4.4 · VecDeque, LinkedList, and BinaryHeap

What's covered?

  • VecDeque as a growable ring buffer — push_front, push_back, make_contiguous, as_slices, plus the push_front_mut/push_back_mut/insert_mut family (stabilized in 1.95).
  • VecDeque::retain_back (1.99) — the front-side counterpart of truncate: keep only the last n elements.
  • Why LinkedList is almost never what you want (cache locality, allocation overhead).
  • BinaryHeap as a max-heap priority queue — peek, push, pop, into_sorted_vec.
  • Relaxed T: Ord bounds in 1.94 for some BinaryHeap methods.

Library Components:

  • std::collections::VecDeque
  • std::collections::LinkedList
  • std::collections::BinaryHeap

4.5 · Slices and Arrays: The Foundation Types

What's covered?

  • Slice methods — sort, sort_by, sort_unstable, binary_search, chunks, windows, array_windows (stabilized in 1.94), split, contains, rotate_left, rotate_right, fill, swap, reverse.
  • element_offset (new in 1.94).
  • array::from_fn, array::each_ref, array::each_mut, and the stable alternative to array::try_from_fn (still unstable as of 1.99).
  • Const generic arrays.
  • Range syntax (a..b, a..=b, ..) appears throughout slice indexing — see 14.2 for the full RangeBounds trait and Bound type behind it.
  • For advanced slice algorithms (partition-point, unstable select, group-by), see 25.2.

Library Components:

  • primitive [T] (slice)
  • primitive [T; N] (array)
  • std::slice
  • std::array

Domain 5 — Iterators and Lazy Computation

5.1 · Iterator Fundamentals: The Trait and Its Adapters

What's covered?

  • The Iterator trait and next().
  • Core adapters: map, filter, filter_map, flat_map, flatten, enumerate, zip, chain, take, skip, take_while, skip_while, step_by, cycle, fuse.
  • Laziness — no work happens until consumption.
  • Why iterators are zero-cost abstractions.

Library Components:

  • std::iter::Iterator
  • adapter types in std::iter

5.2 · Consumers, Collectors, and the FromIterator/Extend Traits

What's covered?

  • Terminal operations: collect, fold, reduce, for_each, sum, product, count, any, all, find, position, min, max, min_by, max_by, min_by_key, max_by_key, nth, last, unzip.
  • FromIterator for custom collection types.
  • Extend for appending.
  • collect::<Result<Vec<_>, _>>() pattern.

Library Components:

  • std::iter::FromIterator
  • std::iter::Extend
  • std::iter::Sum
  • std::iter::Product

5.3 · Advanced Iterators: Peekable, Chain, Scan, and Inspect

What's covered?

  • Peekable and its peek, peek_mut, next_if, next_if_eq, next_if_map (new in 1.94).
  • scan for stateful transformations.
  • inspect for debugging pipelines.
  • by_ref to borrow an iterator.
  • cloned vs. copied.
  • intersperse, intersperse_with, and Iterator::array_chunks (all still unstable as of 1.99 — nightly-gated example).

Library Components:

  • std::iter::Peekable
  • std::iter::Scan
  • std::iter::Inspect
  • std::iter::Intersperse

5.4 · DoubleEndedIterator, ExactSizeIterator, and FusedIterator

What's covered?

  • DoubleEndedIterator and next_back — iterating from both ends.
  • rev().
  • ExactSizeIterator and len() — when the compiler knows the exact remaining count.
  • FusedIterator — guaranteeing None forever after the first None; StepBy<I> is fused when I is fused (1.99).
  • How these traits enable optimizations in collect and extend.
  • TrustedLen (unstable but worth knowing about).

Library Components:

  • std::iter::DoubleEndedIterator
  • std::iter::ExactSizeIterator
  • std::iter::FusedIterator

5.5 · Creating Iterators: once, empty, repeat, successors, from_fn

What's covered?

  • Factory functions for iterators: iter::once, iter::once_with, iter::empty, iter::repeat, iter::repeat_with, iter::repeat_n (whose RepeatN gained Default in 1.97), iter::successors, iter::from_fn, iter::from_coroutine (unstable).
  • IntoIterator and why for loops work.
  • Implementing Iterator for custom types.

Library Components:

  • std::iter::once
  • std::iter::empty
  • std::iter::repeat
  • std::iter::successors
  • std::iter::from_fn
  • std::iter::IntoIterator

5.6 · ControlFlow: Short-Circuiting Iterator Operations

What's covered?

  • ControlFlow<B, C> as the generalization of break and continue.
  • How ControlFlow powers the Try trait machinery under ?.
  • Using ControlFlow with Iterator::try_for_each and Iterator::try_fold for early-exit iterations without forcing Result or Option semantics.
  • Implementing custom iterators that respect ControlFlow.
  • How ControlFlow::Break and ControlFlow::Continue replace ad-hoc boolean flags.
  • Relationship to FromResidual (see 2.1).

Library Components:

  • std::ops::ControlFlow
  • std::iter::Iterator::try_for_each
  • std::iter::Iterator::try_fold

Domain 6 — Concurrency and Parallelism

6.1 · Threads: Spawning, Joining, and Thread-Local Storage

What's covered?

  • thread::spawn, JoinHandle, thread::Builder (naming, stack size).
  • thread::current, thread::park, thread::unpark.
  • thread_local! macro and LocalKey<T> (including LocalKey<Cell<T>>::update, stable since 1.99).
  • Scoped threads with thread::scope — borrowing stack data across threads without Arc.
  • When thread::spawn returns an error.

Library Components:

  • std::thread
  • std::thread::spawn
  • std::thread::Builder
  • std::thread::JoinHandle
  • std::thread::scope
  • thread_local!
  • std::thread::LocalKey

6.2 · Mutex, RwLock, and Poison Recovery

What's covered?

  • Mutex<T> — wrapping data, lock(), try_lock().
  • MutexGuard and RAII.
  • RwLock<T> — read(), write(), try_read(), try_write().
  • Poison: what it is, PoisonError::into_inner() for recovery.
  • Condvar for wait/notify patterns.
  • When RwLock beats Mutex and when it doesn't (writer starvation).

Library Components:

  • std::sync::Mutex
  • std::sync::MutexGuard
  • std::sync::RwLock
  • std::sync::RwLockReadGuard
  • std::sync::RwLockWriteGuard
  • std::sync::Condvar
  • std::sync::PoisonError
  • std::sync::TryLockError

6.3 · Atomic Types and Their Operations

What's covered?

  • The atomic types: AtomicBool, AtomicI8 through AtomicI64, AtomicU8 through AtomicU64, AtomicPtr, AtomicUsize, AtomicIsize.
  • Operations: load, store, swap, fetch_add, fetch_sub, fetch_or, fetch_and, fetch_xor, fetch_update (a legacy spelling, deprecated since 1.99 in favor of try_update), and the closure-based update/try_update (stabilized in 1.95).
  • from_mut / from_mut_slice / get_mut_slice (1.98) to view exclusive &mut integers as atomics and back.
  • Lock-free counters and flags using only Relaxed and the "when in doubt" default SeqCst.
  • When an atomic beats a Mutex and when it doesn't.
  • Memory orderings appear only as a usage rule of thumb here — the full ordering model is Tutorial 6.4.

Library Components:

  • std::sync::atomic::AtomicBool
  • std::sync::atomic::AtomicUsize
  • std::sync::atomic::AtomicPtr
  • std::sync::atomic::Ordering

6.4 · Memory Ordering: Relaxed, Acquire/Release, and SeqCst

What's covered?

  • What each Ordering guarantees and when to use it: Relaxed, Acquire, Release, AcqRel, SeqCst.
  • The happens-before relation illustrated with the message-passing pattern (data + ready-flag).
  • compare_exchange vs. compare_exchange_weak and the spurious-failure retry loop idiom.
  • fence and compiler_fence.
  • Common bugs: assuming Relaxed orders unrelated memory, mixing orderings inconsistently between load and store sides.

Library Components:

  • std::sync::atomic::Ordering
  • std::sync::atomic::fence
  • std::sync::atomic::compiler_fence

6.5 · Channels: mpsc and mpmc Message Passing

What's covered?

  • mpsc::channel (unbounded) and mpsc::sync_channel (bounded).
  • Sender, SyncSender, Receiver.
  • send, try_send, recv, try_recv, recv_timeout.
  • The mpmc module (multi-producer, multi-consumer — still unstable as of 1.99; demonstrated with a nightly-gated example, with the "clone the Receiver" pattern it will enable).
  • Choosing between channels and shared state.
  • Backpressure with bounded channels.

Library Components:

  • std::sync::mpsc
  • std::sync::mpmc
  • Sender
  • Receiver
  • SyncSender
  • RecvError
  • SendError
  • TryRecvError
  • TrySendError

6.6 · Once, OnceLock, LazyLock, LazyCell: One-Time Initialization

What's covered?

  • The full picture of lazy and once-initialization types.
  • OnceCell (single-threaded, no closure) vs. LazyCell (single-threaded, with closure).
  • OnceLock (multi-threaded, no closure) vs. LazyLock (multi-threaded, with closure).
  • Once and call_once for global one-shot init.
  • get, get_mut, force, force_mut (new in 1.94) — checking initialization state without forcing.
  • From<T> for pre-initialized LazyCell/LazyLock (stabilized in 1.96).
  • When to use static with LazyLock vs. a field with LazyCell.
  • Poisoning behavior differences between LazyLock and Mutex.
  • The four-cell decision matrix.

Library Components:

  • std::sync::Once
  • std::sync::OnceLock
  • std::sync::LazyLock
  • std::cell::OnceCell
  • std::cell::LazyCell

6.7 · Barrier and Rendezvous Synchronization

What's covered?

  • Barrier for synchronizing a fixed number of threads at a checkpoint — all threads block until the last one arrives.
  • BarrierWaitResult and is_leader() for designating one thread to do post-rendezvous work.
  • Constructing phased algorithms (map-reduce, parallel simulation steps) with repeated barrier usage.
  • Comparison with Condvar (6.2) and channels (6.5) for synchronization: when Barrier is the right tool.

Library Components:

  • std::sync::Barrier
  • std::sync::BarrierWaitResult

6.8 · Send, Sync, and the Marker Trait Contracts

What's covered?

  • Why Send and Sync are auto traits.
  • What breaks Send (e.g., Rc<T>).
  • What breaks Sync (e.g., Cell<T>, RefCell<T>).
  • PhantomData to manually opt out.
  • Unsafe implementations of Send/Sync and when they're justified.
  • How Arc<Mutex<T>> satisfies both.
  • The role of Unpin in this landscape.

Library Components:

  • std::marker::Send
  • std::marker::Sync
  • std::marker::Unpin
  • std::marker::PhantomData
  • std::marker::PhantomPinned

Domain 7 — Smart Pointers and Heap Allocation

7.1 · Box<T>: The Simplest Heap Allocation

What's covered?

  • Box::new, Box::into_raw, Box::from_raw, Box::leak.
  • Box::into_non_null / Box::from_non_null (1.99): the same ownership round trip with a NonNull<T> pointer.
  • Boxing trait objects (Box<dyn Trait>).
  • Boxing recursive types.
  • Box::into_inner (still unstable as of 1.99 — nightly-gated example; the stable equivalent is the deref-move *boxed).
  • The Deref and DerefMut implementations.
  • Stack vs. heap placement semantics.

Library Components:

  • std::boxed::Box

7.2 · Rc<T> and Arc<T>: Reference Counting Strategies

What's covered?

  • Rc<T> for single-threaded reference counting.
  • Arc<T> for thread-safe reference counting.
  • strong_count, weak_count, Rc::try_unwrap, Arc::try_unwrap.
  • make_mut (clone-on-write).
  • Weak<T> references to break cycles.
  • Rc::new_cyclic for self-referential data.
  • Why Rc is not Send.

Library Components:

  • std::rc::Rc
  • std::rc::Weak
  • std::sync::Arc
  • std::sync::Weak

7.3 · Cell<T> and RefCell<T>: Interior Mutability

What's covered?

  • Cell<T> — get, set, replace, take.
  • Why Cell requires Copy for get.
  • RefCell<T> — borrow, borrow_mut, try_borrow, try_borrow_mut.
  • Runtime borrow checking.
  • BorrowError and BorrowMutError.
  • OnceCell and LazyCell for single-assignment cells (covered in full at 6.6).
  • Array-of-cells conversions: Cell<[T; N]> as [Cell<T>; N] via AsRef (stabilized in 1.95) alongside as_slice_of_cells.
  • The UnsafeCell<T> primitive underneath.

Library Components:

  • std::cell::Cell
  • std::cell::RefCell
  • std::cell::Ref
  • std::cell::RefMut
  • std::cell::UnsafeCell

Domain 8 — I/O System

8.1 · Read, Write, BufRead: The I/O Trait Hierarchy

What's covered?

  • The three core traits: Read (bytes in), Write (bytes out), BufRead (buffered reading with read_line, lines, split).
  • BufReader and BufWriter wrappers.
  • read_to_string, read_to_end, read_exact.
  • write_all vs. write.
  • flush.
  • Chaining readers with chain.
  • take to limit reads.
  • io::copy for streaming data between a Read and a Write without intermediate allocation (it specializes internally for buffered sources and sinks; as of 1.99, std has no public io::copy_buf).
  • Note: io::Write (byte streams) is distinct from fmt::Write (string/buffer formatting) — both work with write! and writeln! macros via separate trait implementations; see 3.2 for the fmt::Write side.

Library Components:

  • std::io::Read
  • std::io::Write
  • std::io::BufRead
  • std::io::BufReader
  • std::io::BufWriter
  • std::io::LineWriter
  • std::io::copy

8.2 · Cursor, Sink, Empty, Repeat: In-Memory I/O and Binary Parsing

What's covered?

  • Cursor<T> for treating Vec<u8> or &[u8] as a reader/writer with seek support.
  • io::empty() as /dev/null for reads.
  • io::sink() as /dev/null for writes.
  • io::repeat(byte) for infinite byte streams.
  • Binary format parsing: using Cursor<&[u8]> to sequentially parse a binary format — combining Read with Seek to navigate offset tables, reading u32s and f64s in specific byte orders (see 18.1 for endian conversion helpers), writing binary data back with Cursor<Vec<u8>>.
  • Use case: testing I/O code without files and parsing binary file headers (e.g., BMP, PNG).

Library Components:

  • std::io::Cursor
  • std::io::Empty
  • std::io::Sink
  • std::io::Repeat
  • std::io::empty
  • std::io::sink
  • std::io::repeat

8.3 · Seek and Byte-Level Navigation

What's covered?

  • The Seek trait and SeekFrom enum (Start, End, Current).
  • stream_position as a convenience.
  • Using Seek with BufReader (the gotcha of stale buffers).
  • seek_relative on BufReader.
  • Use case: parsing binary file formats with offset tables.

Library Components:

  • std::io::Seek
  • std::io::SeekFrom

8.4 · std::io::Error: Anatomy of I/O Errors

What's covered?

  • io::Error construction: Error::new, Error::other, Error::from_raw_os_error.
  • ErrorKind enum — all variants and when each occurs.
  • error.kind() matching.
  • Custom error payloads.
  • Converting other error types into io::Error.
  • The io::Result<T> alias.

Library Components:

  • std::io::Error
  • std::io::ErrorKind
  • std::io::Result

8.5 · stdin, stdout, stderr: Standard Streams

What's covered?

  • io::stdin(), io::stdout(), io::stderr() — their locking model (lock() for performance).
  • print!, println!, eprint!, eprintln!.
  • StdinLock, StdoutLock.
  • Why println! panics on broken pipes and how to handle it.
  • Buffering behavior differences between stdout and stderr.

Library Components:

  • std::io::stdin
  • std::io::stdout
  • std::io::stderr
  • std::io::Stdin
  • std::io::Stdout
  • std::io::Stderr
  • print!
  • println!
  • eprint!
  • eprintln!

Domain 9 — Filesystem Operations

9.1 · Reading, Writing, and Creating Files

What's covered?

  • File::open, File::create, File::create_new.
  • OpenOptions builder — read, write, append, truncate, create, create_new.
  • Reading a file to string with fs::read_to_string.
  • Writing with fs::write.
  • File as Read + Write + Seek.
  • Setting permissions on open.

Library Components:

  • std::fs::File
  • std::fs::OpenOptions
  • std::fs::read_to_string
  • std::fs::read
  • std::fs::write

9.2 · Directory Operations and Metadata

What's covered?

  • fs::create_dir, fs::create_dir_all, fs::remove_dir, fs::remove_dir_all.
  • fs::read_dir and the DirEntry iterator.
  • fs::metadata, fs::symlink_metadata.
  • The Metadata struct — is_file, is_dir, is_symlink, len, modified, created, accessed, permissions.
  • fs::set_permissions.
  • fs::set_times and fs::set_times_nofollow (1.99) with the FileTimes builder, to set timestamps by path.

Library Components:

  • std::fs
  • std::fs::DirEntry
  • std::fs::Metadata
  • std::fs::Permissions
  • std::fs::FileType
  • std::fs::FileTimes

9.3 · Path and PathBuf: Cross-Platform Path Manipulation

What's covered?

  • Path vs. PathBuf (borrowed vs. owned).
  • join, push, pop, set_extension, set_file_name.
  • Components: parent, file_name, file_stem, extension, components, ancestors.
  • canonicalize for resolving symlinks.
  • Platform differences (separators, roots, prefixes).
  • Path::display for lossy printing.

Library Components:

  • std::path::Path
  • std::path::PathBuf
  • std::path::Component
  • std::path::Prefix
  • std::path::MAIN_SEPARATOR

What's covered?

  • fs::copy, fs::rename, fs::hard_link.
  • Platform-specific symlink functions in std::os::unix::fs::symlink and std::os::windows::fs::symlink_file/symlink_dir.
  • fs::read_link.
  • Handling cross-device moves (rename fails, must copy + delete).
  • Atomicity guarantees (or lack thereof).

Library Components:

  • std::fs::copy
  • std::fs::rename
  • std::fs::hard_link
  • std::fs::read_link
  • std::os::unix::fs
  • std::os::windows::fs

Domain 10 — Networking

10.1 · TCP: TcpListener and TcpStream

What's covered?

  • TcpListener::bind, incoming(), accept().
  • TcpStream::connect, connect_timeout.
  • Reading and writing on streams.
  • set_nonblocking, set_read_timeout, set_write_timeout, set_nodelay.
  • shutdown with Shutdown::Read/Write/Both.
  • peek.
  • try_clone for sharing a socket.

Library Components:

  • std::net::TcpListener
  • std::net::TcpStream
  • std::net::Shutdown

10.2 · UDP: Connectionless Communication

What's covered?

  • UdpSocket::bind, send_to, recv_from.
  • connect + send/recv for connected UDP.
  • set_broadcast, set_multicast_loop_v4, join_multicast_v4, leave_multicast_v4.
  • set_nonblocking.
  • Use case: building a simple DNS resolver or game server.

Library Components:

  • std::net::UdpSocket

10.3 · IP Addresses and Socket Addresses

What's covered?

  • IpAddr, Ipv4Addr, Ipv6Addr — parsing, constructing, classification (is_loopback, is_multicast, is_private, is_global).
  • SocketAddr, SocketAddrV4, SocketAddrV6.
  • ToSocketAddrs trait for resolution (including DNS).
  • Why ToSocketAddrs blocks and how to handle that.

Library Components:

  • std::net::IpAddr
  • std::net::Ipv4Addr
  • std::net::Ipv6Addr
  • std::net::SocketAddr
  • std::net::SocketAddrV4
  • std::net::SocketAddrV6
  • std::net::ToSocketAddrs
  • std::net::AddrParseError

Domain 11 — Time and Duration

11.1 · Instant, SystemTime, and Duration

What's covered?

  • Instant::now() for monotonic timing (benchmarks, timeouts).
  • SystemTime::now() for wall-clock time.
  • UNIX_EPOCH.
  • Duration — from_secs, from_millis, from_nanos, as_secs_f64, as_secs_f32.
  • Arithmetic on Instant and SystemTime (addition, subtraction, elapsed).
  • checked_add, checked_sub, saturating_*.
  • SystemTimeError and its duration() method for negative differences.

Library Components:

  • std::time::Instant
  • std::time::SystemTime
  • std::time::Duration
  • std::time::UNIX_EPOCH
  • std::time::SystemTimeError

11.2 · Thread Sleep, Timeouts, and Timed Operations

What's covered?

  • thread::sleep (and thread::sleep_until, still unstable as of 1.99 — mention only).
  • Using Duration with Mutex::try_lock, Condvar::wait_timeout, mpsc::Receiver::recv_timeout, TcpStream::set_read_timeout.
  • Building a simple rate limiter with Instant.
  • Spin-wait vs. sleep tradeoffs.
  • hint::spin_loop for busy waiting.

Library Components:

  • std::thread::sleep
  • std::time::Duration
  • std::hint::spin_loop

Domain 12 — Process and Environment Interaction

12.1 · Environment Variables, Args, and Current Directory

What's covered?

  • env::var, env::var_os, env::vars, env::vars_os.
  • env::set_var (unsafe since 1.84), env::remove_var.
  • env::args, env::args_os.
  • env::current_dir, env::set_current_dir.
  • env::current_exe.
  • env::temp_dir, env::home_dir (un-deprecated in 1.87 after its Windows behavior was fixed).
  • The safety concerns around set_var in multithreaded contexts.

Library Components:

  • std::env
  • std::env::Args
  • std::env::ArgsOs
  • std::env::Vars
  • std::env::VarsOs
  • std::env::VarError

12.2 · Spawning and Managing Child Processes

What's covered?

  • Command::new, arg, args, env, current_dir, stdin, stdout, stderr.
  • Stdio::piped, Stdio::null, Stdio::inherit.
  • spawn vs. output vs. status.
  • Child — wait, wait_with_output, kill, try_wait.
  • Piping between processes.
  • ExitStatus and ExitCode.
  • Termination — the trait that allows fn main() -> Result<(), E> and custom process exit codes; how ExitCode::from and Termination::report work together.

Library Components:

  • std::process::Command
  • std::process::Child
  • std::process::Output
  • std::process::Stdio
  • std::process::ExitStatus
  • std::process::ExitCode
  • std::process::Termination
  • std::process::exit
  • std::process::abort

Domain 13 — Comparing, Ordering, and Hashing

13.1 · PartialEq, Eq, PartialOrd, Ord: The Comparison Hierarchy

What's covered?

  • Why four traits? The partial equivalence relation (NaN ≠ NaN).
  • Deriving vs. manual implementation.
  • Ord::cmp, PartialOrd::partial_cmp.
  • Reverse for descending sorts.
  • cmp::min/cmp::max as standalone functions and Ord::clamp (plus the float inherent clamp).
  • Implementing comparisons across different types (PartialEq<Rhs>).
  • Consistency contract: Eq requires reflexivity; Ord requires totality.

Library Components:

  • std::cmp::PartialEq
  • std::cmp::Eq
  • std::cmp::PartialOrd
  • std::cmp::Ord
  • std::cmp::Ordering
  • std::cmp::Reverse
  • std::cmp::min
  • std::cmp::max
  • std::cmp::min_by
  • std::cmp::max_by
  • std::cmp::min_by_key
  • std::cmp::max_by_key

13.2 · Custom Hashing: Implementing Hash and Building Hashers

What's covered?

  • The Hash trait and its hash method.
  • Hasher trait for state machines.
  • BuildHasher for constructing hashers.
  • DefaultHasher (SipHash 1-3).
  • The hash/eq contract (equal values must have equal hashes).
  • Writing a custom Hasher.
  • hash_map::RandomState for DOS resistance.
  • When and why you'd want a non-random hasher (deterministic tests, performance).
  • The Hash/Hasher/BuildHasher trio is introduced in context of HashMap at 4.2; this tutorial goes deeper on custom implementations.

Library Components:

  • std::hash::Hash
  • std::hash::Hasher
  • std::hash::BuildHasher
  • std::hash::BuildHasherDefault
  • std::hash::RandomState
  • std::hash::DefaultHasher

Domain 14 — Operator Overloading

14.1 · Arithmetic and Bitwise Operators

What's covered?

  • Add, Sub, Mul, Div, Rem and their *Assign variants.
  • Neg for unary minus.
  • Bitwise: BitAnd, BitOr, BitXor, Not, Shl, Shr and *Assign.
  • Implementing operators for custom numeric types.
  • Operator overloading with different RHS types.

Library Components:

  • std::ops::Add through std::ops::ShrAssign
  • std::ops::Neg
  • std::ops::Not

14.2 · Index, Deref, and the Range Operator Family

What's covered?

  • Index and IndexMut for [] syntax.
  • Deref and DerefMut — deref coercion rules and the "smart pointer" pattern.
  • Range, RangeInclusive, RangeFrom, RangeTo, RangeToInclusive, RangeFull — construction, iteration, and use in slice indexing.
  • The RangeBounds<T> trait — start_bound, end_bound, contains — and how to write functions that accept any range expression.
  • Bound::Included, Bound::Excluded, Bound::Unbounded.
  • Using ranges for slicing, iteration, and pattern matching.
  • Exclusive range patterns in match (stabilized 1.80).
  • The .. and ..= operators as syntactic sugar for these types.
  • The new core::range generation (stabilized in 1.96, RFC 3550): range::Range, range::RangeFrom, range::RangeInclusive, range::RangeToInclusive are Copy and implement IntoIterator instead of Iterator — why that matters, converting between legacy and new range types, and the future-edition migration outlook.
  • std::range::legacy (1.98) re-exports the iterator-style ops range types under a name that marks them as the generation .. sugar still builds.

Library Components:

  • std::ops::Index
  • std::ops::IndexMut
  • std::ops::Deref
  • std::ops::DerefMut
  • std::ops::Range
  • std::ops::RangeInclusive
  • std::ops::RangeFrom
  • std::ops::RangeTo
  • std::ops::RangeToInclusive
  • std::ops::RangeFull
  • std::ops::RangeBounds
  • std::ops::Bound
  • std::range
  • std::range::legacy

14.3 · Fn, FnMut, FnOnce: Closures as Trait Objects

What's covered?

  • The three closure traits and their hierarchy (FnOnce ⊇ FnMut ⊇ Fn).
  • Why closures implement different traits based on capture behavior.
  • Using closures in function signatures (impl Fn, Box<dyn FnMut>, fn pointer).
  • The move keyword.
  • Closure size and when they allocate.
  • Returning closures from functions.

Library Components:

  • std::ops::Fn
  • std::ops::FnMut
  • std::ops::FnOnce

Domain 15 — Asynchronous Programming Primitives

15.1 · Future, Poll, and the Async Machinery

What's covered?

  • Future trait and poll.
  • Poll::Ready vs. Poll::Pending.
  • Context and Waker.
  • Why std provides the traits but no runtime.
  • The relationship to async/await syntax.
  • async fn desugaring.
  • Building a minimal block_on executor with only the standard library (std::task::Wake + Arc + thread::park/unpark) — no external crates.

Library Components:

  • std::future::Future
  • std::future::poll_fn
  • std::future::pending
  • std::future::ready
  • std::task::Poll
  • std::task::Context
  • std::task::Waker
  • std::task::RawWaker
  • std::task::RawWakerVTable
  • std::task::Wake

15.2 · Pin: Why Futures Need Pinning

What's covered?

  • The self-referential future problem, shown concretely with an async block that borrows across an .await.
  • The Pin<P> contract — what it prevents and what it promises.
  • Unpin as the escape hatch and why almost every type is Unpin.
  • pin! macro for stack pinning; Box::pin for heap pinning.
  • Pin::new (requires Unpin).
  • PhantomPinned to opt out of Unpin.

Library Components:

  • std::pin::Pin
  • std::pin::pin!
  • std::boxed::Box::pin
  • std::marker::Unpin
  • std::marker::PhantomPinned

15.3 · Advanced Pinning: Unsafe Construction and Structural Projection

What's covered?

  • Pin::new_unchecked and the invariants the caller must uphold.
  • Structural vs. non-structural pinning — deciding per field whether pinning propagates.
  • Hand-writing safe pin projections (the pattern behind the pin-project crate).
  • Pin::as_mut, Pin::get_mut, Pin::into_inner_unchecked.
  • Building a correct self-referential type with PhantomPinned + NonNull.

Library Components:

  • std::pin::Pin
  • std::ptr::NonNull
  • std::marker::PhantomPinned

Domain 16 — Memory Management and Unsafe Primitives

16.1 · std::mem: Swaps, Sizes, and Transmutes

What's covered?

  • mem::size_of, mem::size_of_val, mem::align_of, mem::align_of_val.
  • mem::size_of_val_raw, mem::align_of_val_raw, and Layout::for_value_raw (1.99): size and alignment from a raw pointer, when a reference is not permitted.
  • mem::swap, mem::replace, mem::take (replaces with default).
  • mem::drop (explicit drop).
  • mem::forget (leaking intentionally).
  • mem::transmute — power and peril.
  • mem::zeroed, mem::uninitialized (deprecated).
  • mem::ManuallyDrop for controlled destruction order (including the 1.98-documented guarantee that moving ManuallyDrop<Box<T>> after dropping the box is not UB).
  • mem::discriminant for comparing enum variants.

Library Components:

  • std::mem::*

16.2 · MaybeUninit: Safe Patterns for Uninitialized Memory

What's covered?

  • Why MaybeUninit<T> exists (replacing mem::uninitialized).
  • MaybeUninit::uninit, MaybeUninit::new, assume_init, assume_init_ref, assume_init_mut, assume_init_drop.
  • Initializing arrays element-by-element; the MaybeUninit<[T; N]> ⇄ [MaybeUninit<T>; N] conversions (stabilized in 1.95).
  • MaybeUninit::zeroed.
  • Use case: building a fixed-capacity buffer without default constructors.

Library Components:

  • std::mem::MaybeUninit

16.3 · Raw Pointers in Practice: NonNull, Copying, and Raw References

What's covered?

  • ptr::null, ptr::null_mut, and NonNull<T> for non-null guarantees (plus the niche optimization it enables).
  • Creating raw pointers with &raw const / &raw mut (stabilized 1.82, superseding addr_of!).
  • ptr::read and ptr::write for moving values through raw pointers.
  • ptr::copy vs. ptr::copy_nonoverlapping (memmove vs. memcpy semantics).
  • ptr::drop_in_place.
  • ptr::from_ref, ptr::from_mut.
  • The patterns most likely to appear in safe wrapper code.

Library Components:

  • std::ptr::NonNull
  • std::ptr::null
  • std::ptr::read
  • std::ptr::write
  • std::ptr::copy
  • std::ptr::copy_nonoverlapping
  • std::ptr::drop_in_place
  • &raw operators

16.4 · Pointer Arithmetic, Volatile, and Provenance

What's covered?

  • Pointer arithmetic — offset, add, sub, wrapping_add — and the UB conditions that separate them.
  • read_volatile/write_volatile and what volatile does (and does not) guarantee.
  • Strict provenance APIs (stabilized 1.84): addr, with_addr, map_addr; exposed provenance: expose_provenance, with_exposed_provenance.
  • Why pointer↔integer round-trips are subtler than they look.
  • ptr::dangling for well-aligned sentinel pointers.

Library Components:

  • std::ptr
  • pointer primitive methods
  • std::ptr::dangling

16.5 · Global Allocator and Allocation APIs

What's covered?

  • The GlobalAlloc trait: alloc, dealloc, realloc, alloc_zeroed.
  • Layout — size and alignment requirements; composing layouts with Layout::extend (stable since 1.44) and with Layout::repeat, Layout::repeat_packed, Layout::extend_packed, and Layout::dangling_ptr (stabilized in 1.95); Layout::for_value_raw (1.99, shown in 16.1).
  • #[global_allocator] attribute for replacing the default allocator.
  • alloc::alloc, alloc::dealloc, alloc::handle_alloc_error.
  • Why Allocator (the parameterized allocator trait) is still unstable but worth tracking.

Library Components:

  • std::alloc::GlobalAlloc
  • std::alloc::Layout
  • std::alloc::alloc
  • std::alloc::dealloc
  • std::alloc::realloc
  • std::alloc::handle_alloc_error
  • std::alloc::System

Domain 17 — Type System Utilities

17.1 · Any and Dynamic Typing

What's covered?

  • Any trait and TypeId.
  • Downcasting with downcast_ref, downcast_mut, downcast (on Box<dyn Any>).
  • TypeId::of::<T>() for runtime type identification.
  • type_name::<T>() and type_name_of_val for human-readable type names in diagnostics and generic error messages.
  • Limitations of type_name: output format is not guaranteed to be stable or unique across crates — do not use for serialization.
  • Use cases: heterogeneous collections, plugin architectures, error downcasting, logging.
  • The 'static requirement on Any.

Library Components:

  • std::any::Any
  • std::any::TypeId
  • std::any::type_name
  • std::any::type_name_of_val

17.2 · Marker Traits: Sized, Copy, Send, Sync, Unpin

What's covered?

  • Sized — the implicit bound and ?Sized for unsized types.
  • Copy semantics vs. Clone.
  • Send and Sync (covered in depth in 6.8 but touched on here from the type system perspective).
  • Unpin and its relationship to Pin.
  • PhantomData<T> for expressing unused type parameters, variance, and lifetime relationships.
  • PhantomPinned.

Library Components:

  • std::marker::Sized
  • std::marker::Copy
  • std::marker::Send
  • std::marker::Sync
  • std::marker::Unpin
  • std::marker::PhantomData
  • std::marker::PhantomPinned

17.3 · The Default Trait and Default Values

What's covered?

  • Deriving Default.
  • Implementing Default manually.
  • Option::unwrap_or_default().
  • HashMap::entry(..).or_default().
  • Using Default with mem::take.
  • Interaction with #[non_exhaustive].
  • Use case: builder pattern fallbacks, struct initialization with ..Default::default().

Library Components:

  • std::default::Default

Domain 18 — Numeric Types and Math

18.1 · Integer Methods: Checked, Wrapping, Saturating, Overflowing

What's covered?

  • The four arithmetic strategies on every integer type.
  • checked_add, wrapping_mul, saturating_sub, overflowing_div.
  • pow, isqrt.
  • leading_zeros, trailing_zeros, count_ones, rotate_left, rotate_right, reverse_bits, swap_bytes.
  • The bit-query family stabilized in 1.97: bit_width, highest_one, lowest_one, isolate_highest_one, isolate_lowest_one (also on NonZero integers).
  • Endian conversion: to_be, to_le, from_be_bytes, to_le_bytes, to_ne_bytes, from_le_bytes, from_ne_bytes — the primary tools for binary protocol encoding/decoding and working with [u8] byte buffers.
  • [u8]::escape_ascii for displaying raw byte sequences.
  • NonZero types, their MIN/MAX constants, const methods, and the niche optimization (Option<NonZeroU32> is the same size as u32).
  • Associated constants (i32::MAX) are the only current spelling: the legacy module constants (std::i32::MAX) and the min_value()/max_value() functions are deprecated since 1.99.

Library Components:

  • Primitive integer types
  • std::num::NonZero*
  • std::num::Wrapping
  • std::num::Saturating

18.2 · Floating-Point: IEEE 754, Special Values, and Math Constants

What's covered?

  • f32 and f64 methods: floor, ceil, round, trunc, fract, abs, signum, copysign, sqrt, cbrt, ln, log2, log10, exp, exp2, sin, cos, tan, asin, acos, atan, atan2, hypot, powi, powf, mul_add (const in 1.94).
  • Algebraic operators algebraic_{add,sub,mul,div,rem} (1.98) that permit reassociation and similar optimizations.
  • NAN, INFINITY, NEG_INFINITY, EPSILON, MIN, MAX, MIN_POSITIVE.
  • New constants: EULER_GAMMA, GOLDEN_RATIO (stabilized in 1.94).
  • is_nan, is_finite, is_infinite, is_subnormal, is_sign_positive, classify, total_cmp.

Library Components:

  • f32
  • f64
  • std::f32::consts
  • std::f64::consts

18.3 · Parsing Numbers: FromStr, Radix, and Formatting

What's covered?

  • str::parse::<i32>() and FromStr.
  • i32::from_str_radix for non-decimal bases.
  • NonZero*::from_str_radix (1.98) so a successful parse is already nonzero.
  • ParseIntError, ParseFloatError.
  • Formatting numbers: padding, precision, sign display.
  • num::IntErrorKind — distinguishing empty, invalid digit, overflow, underflow, zero.
  • Converting between integer sizes safely with TryFrom (introduced in Tutorial 1.3); since 1.99 the TryFromIntError message says if the value is too large or too small.

Library Components:

  • std::str::FromStr
  • integer and float from_str_radix
  • std::num::ParseIntError
  • std::num::ParseFloatError
  • std::num::IntErrorKind

Domain 19 — Macros from the Standard Library

19.1 · Essential Macros: assert, dbg, todo, unimplemented, unreachable

What's covered?

  • assert!, assert_eq!, assert_ne! — custom messages, when they compile away (debug_assert_*).
  • assert_matches! and debug_assert_matches! for pattern-based assertions (stabilized in 1.96; not in the prelude — must be imported).
  • dbg! — how it prints file/line/expression and returns the value.
  • todo! vs. unimplemented! vs. unreachable! — intent signaling.
  • panic! message formatting.

Library Components:

  • assert!
  • assert_eq!
  • assert_ne!
  • assert_matches!
  • debug_assert!
  • debug_assert_eq!
  • debug_assert_ne!
  • debug_assert_matches!
  • dbg!
  • todo!
  • unimplemented!
  • unreachable!
  • panic!

19.2 · Compile-Time Macros: cfg, env, include, concat, stringify

What's covered?

  • cfg! for runtime config checks.
  • cfg_select! (stabilized in 1.95) as a compile-time "match on cfg predicates" that replaces the cfg-if crate.
  • env! and option_env! for compile-time env vars.
  • include_str! and include_bytes! for embedding files.
  • concat! for compile-time string concatenation.
  • stringify! for turning tokens into a string.
  • file!, line!, column!, module_path!.
  • compile_error! for custom compile-time errors.
  • cfg! vs. #[cfg(...)] vs. cfg_select!.

Library Components:

  • cfg!
  • cfg_select!
  • env!
  • option_env!
  • include_str!
  • include_bytes!
  • include!
  • concat!
  • stringify!
  • file!
  • line!
  • column!
  • module_path!
  • compile_error!

19.3 · vec!, format!, write!, and Other Constructor Macros

What's covered?

  • vec![1, 2, 3] and vec![0; n].
  • format! for string building.
  • write! and writeln! for writing to any fmt::Write or io::Write.
  • matches! for boolean pattern matching.
  • todo! as a typed placeholder.
  • thread_local!.
  • Using these macros effectively in real code.

Library Components:

  • vec!
  • format!
  • write!
  • writeln!
  • matches!
  • thread_local!

Domain 20 — FFI (Foreign Function Interface)

20.1 · C Types and Calling Conventions

What's covered?

  • std::ffi C-compatible types: c_char, c_int, c_long, c_float, c_double, c_void, etc.
  • extern "C" blocks.
  • Calling conventions: extern "C", extern "system", and extern "stdcall" (a hard error on targets that don't support it — extern "system" is the portable spelling).
  • ABI compatibility and #[repr(C)].
  • Passing and returning structs across the FFI boundary.
  • C-variadic function definitions (unsafe extern "C" fn f(n: c_int, args: ...)) and VaList (stabilized in 1.99).

Library Components:

  • std::ffi::c_char
  • std::ffi::c_int
  • std::ffi::c_void
  • std::ffi::VaList
  • etc.

20.2 · String Marshalling: CString/CStr and OsString/OsStr at the Boundary

What's covered?

  • Creating CString from Rust strings.
  • Handling interior null bytes.
  • Passing CStr to C functions.
  • Receiving C strings as *const c_char and wrapping in CStr.
  • OsStr/OsString for OS-native strings.
  • Platform-specific extensions: OsStrExt on Unix (as raw bytes), OsStringExt on Windows (wide chars).

Library Components:

  • std::ffi::CString
  • std::ffi::CStr
  • std::ffi::NulError
  • std::ffi::OsStr
  • std::ffi::OsString
  • std::os::unix::ffi::OsStrExt
  • std::os::windows::ffi::OsStringExt

Domain 21 — OS-Specific Extensions

21.1 · Unix Extensions: File Descriptors, Permissions, Signals

What's covered?

  • std::os::unix — fs::PermissionsExt (mode bits), fs::MetadataExt (inode, dev, nlink, uid, gid).
  • io::AsRawFd, FromRawFd, IntoRawFd, OwnedFd, BorrowedFd.
  • Unix domain sockets via std::os::unix::net (the abstract-namespace SocketAddrExt is Linux-only, living in std::os::linux::net).
  • process::CommandExt — uid, gid, pre_exec.
  • Pipe and signal concepts.

Library Components:

  • std::os::unix::fs
  • std::os::unix::io
  • std::os::unix::net
  • std::os::unix::process

21.2 · Windows Extensions: Handles, Wide Strings, and Process Creation

What's covered?

  • std::os::windows — io::AsRawHandle, FromRawHandle, IntoRawHandle, OwnedHandle, BorrowedHandle.
  • OsStrExt::encode_wide and OsStringExt::from_wide.
  • fs::MetadataExt (file attributes, creation time).
  • process::CommandExt — creation_flags, raw_arg.
  • Differences from Unix when writing cross-platform code.

Library Components:

  • std::os::windows::fs
  • std::os::windows::io
  • std::os::windows::process
  • std::os::windows::ffi

Domain 22 — Compiler Hints and Low-Level Intrinsics

22.1 · std::hint: Guiding the Optimizer

What's covered?

  • The complete std::hint module.
  • hint::unreachable_unchecked — promises to the compiler (and the UB if you're wrong).
  • hint::spin_loop — yield for spin-wait loops (see also 11.2).
  • hint::black_box — preventing dead code elimination in benchmarks.
  • hint::assert_unchecked for precondition assertions.
  • hint::cold_path (stabilized in 1.95) for marking unlikely branches.
  • When and why to use each.

Library Components:

  • std::hint::unreachable_unchecked
  • std::hint::spin_loop
  • std::hint::black_box
  • std::hint::assert_unchecked
  • std::hint::cold_path

22.2 · SIMD with std::arch: Platform Intrinsics

What's covered?

  • Overview of std::arch for x86, x86_64, ARM, AArch64, WebAssembly.
  • Feature detection at runtime: is_x86_feature_detected!, is_aarch64_feature_detected!.
  • Using SSE/AVX intrinsics within unsafe blocks.
  • AVX-512 FP16 intrinsics (stabilized in 1.94) and AArch64 NEON FP16.
  • #[target_feature(enable = "...")].
  • Why this matters: hot loops in signal processing, compression, cryptography.

Library Components:

  • std::arch::x86_64
  • std::arch::aarch64
  • std::arch::wasm32
  • is_x86_feature_detected!
  • is_aarch64_feature_detected!

Domain 23 — Testing, Debugging, and Pattern Matching

23.1 · Debug Formatting and Diagnostic Output

What's covered?

  • #[derive(Debug)] and when to implement Debug manually.
  • Pretty-printing with {:#?}.
  • dbg! for quick debugging.
  • Writing custom Debug implementations with DebugStruct, DebugTuple, DebugList, DebugMap.
  • fmt::Pointer for printing addresses.
  • type_name::<T>() and type_name_of_val for runtime type inspection (see 17.1 for deeper coverage).

Library Components:

  • std::fmt::Debug
  • std::fmt::DebugStruct
  • std::fmt::DebugTuple
  • std::fmt::DebugList
  • std::fmt::DebugMap
  • std::any::type_name
  • dbg!

23.2 · Assertions, Panics, and Test Harness Integration

What's covered?

  • assert!, assert_eq!, assert_ne! with custom messages.
  • assert_matches! (1.96) for asserting on enum shapes in tests.
  • debug_assert_* variants that compile away in release.
  • #[should_panic] test attribute.
  • #[test] and #[cfg(test)].
  • Using Result<(), E> in test functions.
  • Capturing panics in tests with catch_unwind.
  • Building a custom test framework (overview).

Library Components:

  • assert!
  • assert_eq!
  • assert_ne!
  • debug_assert!
  • std::panic::catch_unwind
  • #[test]
  • #[should_panic]

23.3 · matches!, if let Chains, and Exhaustive Matching Strategies

What's covered?

  • The matches! macro for boolean pattern tests.
  • Using matches! with guards.
  • Nested pattern matching.
  • Exclusive range patterns (start..end, stabilized in 1.80).
  • Combining patterns with |.
  • @ bindings in patterns.
  • The if let and let else constructs; let chains (1.88) and if-let guards in match arms (stabilized in 1.95).
  • How Option, Result, and custom enums interact with pattern matching.

Library Components:

  • matches!
  • std::option::Option
  • std::result::Result
  • language-level pattern syntax

Domain 24 — Dynamic Dispatch and Trait Objects

24.1 · dyn Trait, Vtables, and Object Safety

What's covered?

  • What makes a trait "object safe."
  • The vtable layout — function pointers + size + alignment.
  • Box<dyn Trait>, &dyn Trait, Arc<dyn Trait>.
  • dyn Trait + Send + Sync + 'static bounds.
  • Downcasting with Any.
  • Performance implications of dynamic dispatch vs. monomorphization.
  • dyn Fn(), dyn FnMut(), dyn FnOnce() as callable trait objects.

Library Components:

  • std::any::Any
  • dyn keyword
  • std::boxed::Box
  • std::ops::Fn* traits

Domain 25 — The Contiguous Memory Triumvirate

25.1 · Vec, Boxed Slices, and Arrays: Choosing the Right Container

What's covered?

  • Vec<T> — growable.
  • Box<[T]> — heap-allocated, fixed after conversion.
  • [T; N] — stack-allocated, compile-time size.
  • Conversions between them: Vec::into_boxed_slice(), into_vec() on a Box<[T]>, <[T; N]>::as_slice().
  • When each is optimal (memory overhead, flexibility, stack limits).
  • Using array::from_fn for constructing arrays from closures.
  • Iterating a boxed array: IntoIterator for Box<[T; N]>, &Box<[T; N]>, and &mut Box<[T; N]> (1.99).

Library Components:

  • std::vec::Vec
  • std::boxed::Box
  • primitive [T; N]
  • std::array::from_fn
  • std::array::try_from_fn (unstable as of 1.99 — nightly-gated example)
  • std::boxed::BoxedArrayIntoIter

25.2 · Slice Algorithms: Advanced Sorting, Searching, and Splitting

What's covered?

  • Advanced algorithms not covered in 4.5.
  • sort_by_key, sort_unstable_by_key.
  • binary_search_by, binary_search_by_key, partition_point (find the split point for a sorted predicate).
  • split_at, split_at_mut, split_first, split_last, split_first_mut, split_last_mut.
  • [T]::subslice_range and [T]::strip_circumfix (1.98).
  • chunks_exact, chunks_exact_mut, and the as_chunks family (stabilized in 1.88; Iterator::array_chunks remains unstable as of 1.99).
  • chunk_by (stabilized in 1.77 — the rename of the formerly unstable group_by) for splitting on adjacent-element predicates.
  • select_nth_unstable, select_nth_unstable_by, select_nth_unstable_by_key for partial sorting.

Library Components:

  • Primitive [T] methods
  • std::slice

Domain 26 — Cross-Cutting Patterns

26.1 · The Newtype Pattern with Standard Library Traits

What's covered?

  • Wrapping a type to change its behavior (sorting, hashing, display).
  • Deriving vs. forwarding standard traits on newtypes.
  • Deref/DerefMut for transparent access.
  • From/Into for conversions.
  • Use case: Password(String) that redacts in Debug, Meters(f64) with type-safe arithmetic, SortByName(Person) with custom Ord.

Library Components:

  • std::ops::Deref
  • std::fmt::Debug
  • std::fmt::Display
  • std::cmp::Ord
  • std::convert::From

26.2 · Builder Patterns with Default and Option

What's covered?

  • Using Default::default() for struct initialization with ..Default::default().
  • Option<T> fields for optional configuration.
  • Combining Default with the builder pattern.
  • take and replace on Option for consuming builders.
  • unwrap_or_default chains.
  • Real use case: HTTP request builder, database connection options.

Library Components:

  • std::default::Default
  • std::option::Option
  • std::mem::take
  • std::mem::replace

26.3 · The Iterator + Collect Pattern as a Data Pipeline

What's covered?

  • Composing iterator chains as functional data pipelines.
  • Collecting into different types: Vec<T>, HashMap<K, V>, BTreeMap<K, V>, HashSet<T>, String, Result<Vec<T>, E>, Option<Vec<T>>.
  • Iterator::partition for splitting.
  • Iterator::unzip for destructuring pairs.
  • Performance: avoiding intermediate allocations with extend and chain.

Library Components:

  • std::iter::Iterator
  • std::iter::FromIterator
  • std::iter::Extend

Appendix A — Stabilizations Highlighted from Rust 1.94–1.99

Note: The curriculum targets Rust 1.99 (MSRV; compiler 1.99.0). This table maps stabilizations from releases 1.94 through 1.99 (all verified against the official release notes) to the tutorials that showcase them.

APIStabilizedDomainTutorial
<[T]>::array_windows1.94Collections, Slices4.5, 25.2
<[T]>::element_offset1.94Collections, Slices4.5
LazyCell/LazyLock get, get_mut, force_mut1.94Lazy Evaluation6.6
Peekable::next_if_map1.94Iterators5.3
impl TryFrom<char> for usize1.94Conversions1.3
f32/f64 consts::EULER_GAMMA, consts::GOLDEN_RATIO1.94Numerics18.2
f32::mul_add / f64::mul_add (const)1.94Numerics18.2
AVX-512 FP16 + AArch64 NEON FP16 intrinsics1.94SIMD22.2
Relaxed T: Ord on BinaryHeap methods1.94Collections4.4
cfg_select!1.95Macros19.2
if-let guards in match arms1.95Pattern Matching23.3
Atomic*::update / try_update1.95Concurrency6.3
Vec::push_mut, Vec::insert_mut1.95Collections4.1
VecDeque/LinkedList push_*_mut, insert_mut1.95Collections4.4
impl TryFrom<{integer}> for bool1.95Conversions1.3
MaybeUninit<[T; N]> ⇄ [MaybeUninit<T>; N] conversions1.95Unsafe Memory16.2
Cell<[T; N]>: AsRef<[Cell<T>]> family1.95Interior Mutability7.3
hint::cold_path1.95Compiler Hints22.1
Layout::repeat, Layout::repeat_packed, Layout::extend_packed, Layout::dangling_ptr1.95Allocation16.5
assert_matches!, debug_assert_matches!1.96Macros, Testing19.1, 23.2
core::range::{Range, RangeFrom, RangeInclusive, RangeToInclusive} (RFC 3550)1.96Operators14.2
From<T> for LazyCell/LazyLock1.96Lazy Evaluation6.6
From<T> for AssertUnwindSafe<T>1.96Panics2.3
Integer bit_width, highest_one, lowest_one, isolate_highest_one, isolate_lowest_one (incl. NonZero)1.97Numerics18.1
Default for iter::RepeatN1.97Iterators5.5
char::is_control (const)1.97Text3.5
str::substr_range, [T]::subslice_range1.98Text, Slices3.1, 25.2
str::strip_circumfix, [T]::strip_circumfix1.98Text, Slices3.3, 25.2
core::fmt::NumBuffer, {integer}::format_into1.98Formatting3.2
{f32,f64}::algebraic_{add,sub,mul,div,rem}1.98Numerics18.2
NonZero<{integer}>::from_str_radix1.98Numerics18.3
String::from_utf16le / from_utf16be (and lossy)1.98Text3.1
Atomic*::from_mut, from_mut_slice, get_mut_slice1.98Concurrency6.3
std::range::legacy1.98Operators14.2
bool::ok_or, bool::ok_or_else1.98Error Handling2.1
ManuallyDrop<Box<T>> move-after-drop documented as not UB1.98Memory16.1
String::from_utf8_lossy_owned, FromUtf8Error::into_utf8_lossy1.99Text3.1
NumBuffer re-exported from std::fmt (and alloc::fmt)1.99Formatting3.2
Vec::into_parts, Vec::from_parts1.99Collections4.1
VecDeque::retain_back1.99Collections4.4
FusedIterator for StepBy<I>1.99Iterators5.4
LocalKey<Cell<T>>::update1.99Concurrency, Macros6.1, 19.3
Atomic*::fetch_update deprecated (renamed to try_update)1.99Concurrency6.3
Box::into_non_null, Box::from_non_null1.99Smart Pointers7.1
fs::set_times, fs::set_times_nofollow1.99Filesystem9.2
mem::size_of_val_raw, mem::align_of_val_raw, Layout::for_value_raw1.99Memory, Allocation16.1, 16.5
TryFromIntError messages distinguish "too large" and "too small"1.99Conversions, Numerics1.3, 18.3
Legacy integer and float module constants (std::i32::MAX, std::f64::EPSILON) deprecated1.99Numerics18.1
C-variadic function definitions, core::ffi::VaList1.99FFI20.1
IntoIterator for Box<[T; N]>, &Box<[T; N]>, &mut Box<[T; N]>1.99Contiguous Memory25.1

Appendix B — Tutorial Index by Library Module

ModuleTutorials
std::alloc16.5
std::any17.1, 23.1
std::arch22.2
std::array4.5, 25.1
std::ascii3.5
std::backtrace2.4
std::borrow1.2
std::boxed7.1, 25.1
std::cell6.6, 7.3
std::char3.5
std::clone1.1
std::cmp13.1
std::collections4.1–4.4
std::convert1.3
std::default17.3, 26.2
std::env12.1
std::error2.2
std::ffi3.4, 20.1, 20.2
std::fmt3.2, 23.1
std::fs9.1–9.4
std::future15.1
std::hash4.2, 13.2
std::hint11.2, 22.1
std::io8.1–8.5
std::iter5.1–5.6, 26.3
std::marker6.8, 17.2
std::mem16.1, 16.2, 26.2
std::net10.1–10.3
std::num18.1, 18.3
std::ops5.6, 14.1–14.3
std::option2.1, 23.3
std::os21.1, 21.2
std::panic2.3, 23.2
std::path9.3
std::pin15.2, 15.3
std::preludeP.1
std::process12.2
std::ptr16.3, 16.4
std::rc7.2
std::result2.1, 23.3
std::slice4.5, 25.2
std::str3.1, 3.3
std::string3.1
std::range14.2
std::sync6.1–6.8
std::task15.1
std::thread6.1, 11.2
std::time11.1, 11.2
std::vec4.1, 25.1

Total: 26 domains + prologue, 88 tutorials (~22 hours of video content at an average of 15 min each)