- Welcome to Comprehensive Rust 🦀
- 1. Running the Course
❱
- 1.1. Course Structure
- 1.2. Keyboard Shortcuts
- 1.3. Translations
- 2. Using Cargo
❱
- 2.1. Rust Ecosystem
- 2.2. Code Samples
- 2.3. Running Cargo Locally
- Day 1: Morning
- 3. Welcome
- 4. Hello, World
❱
- 4.1. What is Rust?
- 4.2. Benefits of Rust
- 4.3. Playground
- 5. Types and Values
❱
- 5.1. Hello, World
- 5.2. Variables
- 5.3. Values
- 5.4. Arithmetic
- 5.5. Type Inference
- 5.6. Exercise: Fibonacci
❱
- 5.6.1. Solution
- 6. Control Flow Basics
❱
- 6.1. Blocks and Scopes
- 6.2. if Expressions
- 6.3. match Expressions
- 6.4. Loops
❱
- 6.4.1. for
- 6.4.2. loop
- 6.5. break and continue
❱
- 6.5.1. Labels
- 6.6. Functions
- 6.7. Macros
- 6.8. Exercise: Collatz Sequence
❱
- 6.8.1. Solution
- Day 1: Afternoon
- 7. Welcome
- 8. Tuples and Arrays
❱
- 8.1. Arrays
- 8.2. Tuples
- 8.3. Array Iteration
- 8.4. Patterns and Destructuring
- 8.5. Exercise: Nested Arrays
❱
- 8.5.1. Solution
- 9. References
❱
- 9.1. Shared References
- 9.2. Exclusive References
- 9.3. Slices
- 9.4. Strings
- 9.5. Reference Validity
- 9.6. Exercise: Geometry
❱
- 9.6.1. Solution
- 10. User-Defined Types
❱
- 10.1. Named Structs
- 10.2. Tuple Structs
- 10.3. Enums
- 10.4. Type Aliases
- 10.5. Const
- 10.6. Static
- 10.7. Exercise: Elevator Events
❱
- 10.7.1. Solution
- Day 2: Morning
- 11. Welcome
- 12. Pattern Matching
❱
- 12.1. Irrefutable Patterns
- 12.2. Matching Values
- 12.3. Destructuring Structs
- 12.4. Destructuring Enums
- 12.5. Let Control Flow
❱
- 12.5.1. if let Expressions
- 12.5.2. while let Statements
- 12.5.3. let else
- 12.6. Exercise: Expression Evaluation
❱
- 12.6.1. Solution
- 13. Methods and Traits
❱
- 13.1. Methods
- 13.2. Traits
❱
- 13.2.1. Implementing Traits
- 13.2.2. Supertraits
- 13.2.3. Associated Types
- 13.3. Deriving
- 13.4. Exercise: Generic Logger
❱
- 13.4.1. Solution
- 14. Generics
❱
- 14.1. Generic Functions
- 14.2. Trait Bounds
- 14.3. Generic Data Types
- 14.4. Generic Traits
- 14.5. impl Trait
- 14.6. dyn Trait
- 14.7. Exercise: Generic min
❱
- 14.7.1. Solution
- Day 2: Afternoon
- 15. Welcome
- 16. Closures
❱
- 16.1. Closure Syntax
- 16.2. Capturing
- 16.3. Closure Traits
- 16.4. Exercise: Log Filter
❱
- 16.4.1. Solution
- 17. Standard Library Types
❱
- 17.1. Standard Library
- 17.2. Documentation
- 17.3. Option
- 17.4. Result
- 17.5. String
- 17.6. Vec
- 17.7. HashMap
- 17.8. Exercise: Counter
❱
- 17.8.1. Solution
- 18. Standard Library Traits
❱
- 18.1. Comparisons
- 18.2. Operators
- 18.3. From and Into
- 18.4. Casting
- 18.5. Read and Write
- 18.6. Default, struct update syntax
- 18.7. Exercise: ROT13
❱
- 18.7.1. Solution
- Day 3: Morning
- 19. Welcome
- 20. Memory Management
❱
- 20.1. Review of Program Memory
- 20.2. Approaches to Memory Management
- 20.3. Ownership
- 20.4. Move Semantics
- 20.5. Clone
- 20.6. Copy Types
- 20.7. Drop
- 20.8. Exercise: Builder Type
❱
- 20.8.1. Solution
- 21. Smart Pointers
❱
- 21.1. Box<T>
- 21.2. Rc
- 21.3. Owned Trait Objects
- 21.4. Exercise: Binary Tree
❱
- 21.4.1. Solution
- Day 3: Afternoon
- 22. Welcome
- 23. Borrowing
❱
- 23.1. Borrowing a Value
- 23.2. Borrow Checking
- 23.3. Borrow Errors
- 23.4. Interior Mutability
❱
- 23.4.1. Cell
- 23.4.2. RefCell
- 23.5. Exercise: Wizard's Inventory
❱
- 23.5.1. Solution
- 24. Lifetimes
❱
- 24.1. Borrowing and Functions
- 24.2. Returning Borrows
- 24.3. Multiple Borrows
- 24.4. Borrow Both
- 24.5. Borrow One
- 24.6. Lifetime Elision
- 24.7. Lifetimes in Data Structures
- 24.8. Exercise: Protobuf Parsing
❱
- 24.8.1. Solution
- Day 4: Morning
- 25. Welcome
- 26. Iterators
❱
- 26.1. Motivation
- 26.2. Iterator Trait
- 26.3. Iterator Helper Methods
- 26.4. collect
- 26.5. IntoIterator
- 26.6. Exercise: Iterator Method Chaining
❱
- 26.6.1. Solution
- 27. Modules
❱
- 27.1. Modules
- 27.2. Filesystem Hierarchy
- 27.3. Visibility
- 27.4. Encapsulation
- 27.5. use, super, self
- 27.6. Exercise: Modules for a GUI Library
❱
- 27.6.1. Solution
- 28. Testing
❱
- 28.1. Unit Tests
- 28.2. Other Types of Tests
- 28.3. Compiler Lints and Clippy
- 28.4. Exercise: Luhn Algorithm
❱
- 28.4.1. Solution
- Day 4: Afternoon
- 29. Welcome
- 30. Error Handling
❱
- 30.1. Panics
- 30.2. Result
- 30.3. Try Operator
- 30.4. Try Conversions
- 30.5. Error Trait
- 30.6. thiserror
- 30.7. anyhow
- 30.8. Exercise: Rewriting with Result
❱
- 30.8.1. Solution
- 31. Unsafe Rust
❱
- 31.1. Unsafe
- 31.2. Dereferencing Raw Pointers
- 31.3. Mutable Static Variables
- 31.4. Unions
- 31.5. Unsafe Functions
❱
- 31.5.1. Unsafe Rust Functions
- 31.5.2. Unsafe External Functions
- 31.5.3. Calling Unsafe Functions
- 31.6. Unsafe Traits
- 31.7. Exercise: FFI Wrapper
❱
- 31.7.1. Solution
- Android
- 32. Welcome
- 33. Setup
- 34. Build Rules
❱
- 34.1. Binary
- 34.2. Library
- 35. AIDL
❱
- 35.1. Birthday Service Tutorial
❱
- 35.1.1. Interface
- 35.1.2. Service API
- 35.1.3. Service
- 35.1.4. Server
- 35.1.5. Deploy
- 35.1.6. Client
- 35.1.7. Changing API
- 35.1.8. Updating Implementations
- 35.2. AIDL Types
❱
- 35.2.1. Primitive Types
- 35.2.2. Array Types
- 35.2.3. Sending Objects
- 35.2.4. Parcelables
- 35.2.5. Sending Files
- 36. Testing
❱
- 36.1. GoogleTest
- 36.2. Mocking
- 37. Logging
- 38. Interoperability
❱
- 38.1. With C
❱
- 38.1.1. A Simple C Library
- 38.1.2. Bindgen
- 38.1.3. Running Our Binary
- 38.1.4. A Simple Rust Library
- 38.1.5. Calling Rust from C
- 38.2. With C++
❱
- 38.2.1. The Bridge Module
- 38.2.2. Rust Bridge
- 38.2.3. Generated C++
- 38.2.4. C++ Bridge
- 38.2.5. Shared Types
- 38.2.6. Shared Enums
- 38.2.7. Rust Error Handling
- 38.2.8. C++ Error Handling
- 38.2.9. Additional Types
- 38.2.10. Building for Android: Genrules
- 38.2.11. Building for Android: C++
- 38.2.12. Building for Android: Rust
- 38.3. With Java
- Chromium
- 39. Welcome
- 40. Setup
- 41. Comparing Chromium and Cargo Ecosystems
- 42. Policy
- 43. Build Rules
❱
- 43.1. Unsafe Code
- 43.2. Depending on Rust Code from Chromium C++
- 43.3. Visual Studio Code
- 43.4. Exercise
- 44. Testing
❱
- 44.1. rust_gtest_interop Library
- 44.2. GN Rules for Rust Tests
- 44.3. chromium::import! Macro
- 44.4. Exercise
- 45. Interoperability with C++
❱
- 45.1. Example Bindings
- 45.2. Limitations of CXX
- 45.3. CXX Error Handling
❱
- 45.3.1. Error Handling: QR Example
- 45.3.2. Error Handling: PNG Example
- 45.4. Using CXX in Chromium
- 45.5. Exercise
- 46. Adding Third Party Crates
❱
- 46.1. Configuring Cargo.toml
- 46.2. Configuring gnrt_config.toml
- 46.3. Downloading Crates
- 46.4. Generating gn Build Rules
- 46.5. Resolving Problems
❱
- 46.5.1. Build Scripts Which Generate Code
- 46.5.2. Build Scripts Which Build C++ or Take Arbitrary Actions
- 46.6. Depending on a Crate
- 46.7. Reviews and Audits
- 46.8. Checking into Chromium Source Code
- 46.9. Keeping Crates Up to Date
- 46.10. Exercise
- 47. Bringing It Together - Exercise
- 48. Exercise Solutions
- Bare Metal: Morning
- 49. Welcome
- 50. no_std
❱
- 50.1. A Minimal Example
- 50.2. alloc
- 51. Microcontrollers
❱
- 51.1. Raw MMIO
- 51.2. PACs
- 51.3. HAL Crates
- 51.4. Board Support Crates
- 51.5. The Type State Pattern
- 51.6. embedded-hal
- 51.7. probe-rs and cargo-embed
❱
- 51.7.1. Debugging
- 51.8. Other Projects
- 52. Exercises
❱
- 52.1. Compass
- 52.2. Solutions
- Bare Metal: Afternoon
- 53. Application Processors
❱
- 53.1. Getting Ready to Rust
- 53.2. Inline Assembly
- 53.3. MMIO
- 53.4. Let's Write a UART Driver
❱
- 53.4.1. More Traits
- 53.4.2. Using It
- 53.5. A Better UART Driver
❱
- 53.5.1. Bitflags
- 53.5.2. Multiple Registers
- 53.5.3. Driver
- 53.6. safe-mmio
❱
- 53.6.1. Driver
- 53.6.2. Using It
- 53.7. Logging
❱
- 53.7.1. Using It
- 53.8. Exceptions
- 53.9. aarch64-rt
❱
- 53.9.1. Exceptions
- 53.10. Other Projects
- 54. Useful Crates
❱
- 54.1. zerocopy
- 54.2. aarch64-paging
- 54.3. buddy_system_allocator
- 54.4. tinyvec
- 54.5. spin
- 55. Bare-Metal on Android
❱
- 55.1. vmbase
- 56. Exercises
❱
- 56.1. RTC Driver
- 56.2. Solutions
- Concurrency: Morning
- 57. Welcome
- 58. Threads
❱
- 58.1. Plain Threads
- 58.2. Scoped Threads
- 59. Channels
❱
- 59.1. Senders and Receivers
- 59.2. Unbounded Channels
- 59.3. Bounded Channels
- 60. Send and Sync
❱
- 60.1. Marker Traits
- 60.2. Send
- 60.3. Sync
- 60.4. Examples
- 61. Shared State
❱
- 61.1. Arc
- 61.2. Mutex
- 61.3. Example
- 62. Exercises
❱
- 62.1. Dining Philosophers
- 62.2. Multi-threaded Link Checker
- 62.3. Solutions
- Concurrency: Afternoon
- 63. Welcome
- 64. Async Basics
❱
- 64.1. async/await
- 64.2. Futures
- 64.3. State Machine
- 64.4. Runtimes
❱
- 64.4.1. Tokio
- 64.5. Tasks
- 65. Channels and Control Flow
❱
- 65.1. Async Channels
- 65.2. Join
- 65.3. Select
- 66. Pitfalls
❱
- 66.1. Blocking the Executor
- 66.2. Pin
- 66.3. Async Traits
- 66.4. Cancellation
- 67. Exercises
❱
- 67.1. Dining Philosophers
- 67.2. Broadcast Chat Application
- 67.3. Solutions
- Idiomatic Rust
- 68. Welcome
- 69. Foundations of API Design
❱
- 69.1. Meaningful Doc Comments
❱
- 69.1.1. Who Are You Writing For?
- 69.1.2. Library vs Application docs
- 69.1.3. Anatomy of a Doc Comment
- 69.1.4. Name Drop and Signpost
- 69.1.5. Avoid Redundancy
- 69.1.6. Name and Signature are Not Enough
- 69.1.7. What and Why, not How and Where
- 69.1.8. Exercise
- 69.2. Predictable API
❱
- 69.2.1. Naming conventions
❱
- 69.2.1.1. New
- 69.2.1.2. Get
- 69.2.1.3. Push
- 69.2.1.4. Is
- 69.2.1.5. Mut
- 69.2.1.6. With: Constructor
- 69.2.1.7. With: Copy-and-change
- 69.2.1.8. With: Closures
- 69.2.1.9. With in normal use
- 69.2.1.10. Try
- 69.2.1.11. From
- 69.2.1.12. Into
- 69.2.1.13. Into inner
- 69.2.1.14. By
- 69.2.1.15. Unchecked
- 69.2.1.16. To
- 69.2.1.17. As and Ref
- 69.2.1.18. Raw parts
- 69.2.1.19. Exercise
- 69.2.2. Implementing Common Traits
❱
- 69.2.2.1. Debug
- 69.2.2.2. PartialEq and Eq
- 69.2.2.3. PartialOrd and Ord
- 69.2.2.4. Hash
- 69.2.2.5. Clone
- 69.2.2.6. Copy
- 69.2.2.7. Serialize and Deserialize
- 69.2.2.8. From and Into
- 69.2.2.9. TryFrom and TryInto
- 69.2.2.10. Display
- 70. Leveraging the Type System
❱
- 70.1. Newtype Pattern
❱
- 70.1.1. Semantic Confusion
- 70.1.2. Parse, Don't Validate
- 70.1.3. Is It Encapsulated?
- 70.2. RAII
❱
- 70.2.1. Drop Skipped
- 70.2.2. Mutex
- 70.2.3. Drop Guards
- 70.2.4. Drop Bomb
- 70.2.5. Drop Bomb Forget
- 70.2.6. forget and drop functions
- 70.2.7. Scope Guard
- 70.2.8. Drop Option
- 70.3. Extension Traits
❱
- 70.3.1. Extending Foreign Types
- 70.3.2. Method Resolution Conflicts
- 70.3.3. Trait Method Conflicts
- 70.3.4. Extending Other Traits
- 70.3.5. Should I Define An Extension Trait?
- 70.4. Typestate Pattern
❱
- 70.4.1. Typestate Pattern Example
- 70.4.2. Beyond Simple Typestate
- 70.4.3. Typestate Pattern with Generics
❱
- 70.4.3.1. Serializer: implement Root
- 70.4.3.2. Serializer: implement Struct
- 70.4.3.3. Serializer: implement Property
- 70.4.3.4. Serializer: Complete implementation
- 70.5. Borrow checking invariants
❱
- 70.5.1. Lifetimes and Borrows: the Abstract Rules
- 70.5.2. Single-use values
- 70.5.3. Mutually Exclusive References / "Aliasing XOR Mutability"
- 70.5.4. PhantomData and Types
- 70.5.5. PhantomData and Types (implementation)
- 70.5.6. PhantomData: Lifetimes for External Resources
- 70.5.7. PhantomData: OwnedFd & BorrowedFd
- 70.6. Token Types
❱
- 70.6.1. Permission Tokens
- 70.6.2. Token Types with Data: Mutex Guards
- 70.6.3. Branded pt 1: Variable-specific tokens
- 70.6.4. Branded pt 2: PhantomData and Lifetime Subtyping
- 70.6.5. Branded pt 3: Implementation
- 70.6.6. Branded pt 4: Branded types in action.
- 71. Polymorphism
❱
- 71.1. Refresher
❱
- 71.1.1. Traits
- 71.1.2. Trait Bounds
- 71.1.3. Deriving Traits
- 71.1.4. Default Implementations
- 71.1.5. Supertraits
- 71.1.6. Blanket Implementations
- 71.1.7. Conditional Methods
- 71.1.8. Orphan Rule
- 71.1.9. Statically Sized and Dynamically Sized types
- 71.1.10. Monomorphization and Binary Size
- 71.2. From OOP to Rust
❱
- 71.2.1. Inheritance
- 71.2.2. Why no Inheritance in Rust?
- 71.2.3. Inheritance from Rust's Perspective
- 71.2.4. "Inheritance" in rust and Supertraits
- 71.2.5. Composition over Inheritance
- 71.2.6. Trait Objects and Dynamic Dispatch
- 71.2.7. Dyn Compatibility
- 71.2.8. Generics vs Trait Objects
- 71.2.9. Limits of Trait Objects
- 71.2.10. Heterogeneous Collections
- 71.2.11. The Any Trait
- 71.2.12. Pitfall: Reaching too quickly for dyn Trait
- 71.2.13. Sealed Traits
- 71.2.14. Sealing with Enums
- 71.2.15. Traits for Polymorphism users can extend
- 71.2.16. Problem solving: Break Down the Problem
- Unsafe
- 72. Welcome
- 73. Setup
- 74. Introduction
❱
- 74.1. Defining Unsafe Rust
- 74.2. Purpose of the unsafe keyword
- 74.3. Two roles of the unsafe keyword
- 74.4. Warm Up Examples
❱
- 74.4.1. Using an unsafe block
- 74.4.2. Defining an unsafe function
- 74.4.3. Implementing an unsafe trait
- 74.4.4. Defining an unsafe trait
- 74.5. Characteristics of Unsafe Rust
❱
- 74.5.1. Dangerous
- 74.5.2. Sometimes necessary
- 74.5.3. Sometimes useful
- 74.6. Responsibility shift
- 74.7. Stronger development workflow required
- 74.8. Example: may_overflow
- 75. Safety Preconditions
❱
- 75.1. Common Preconditions
❱
- 75.1.1. Getter example
- 75.2. Semantic preconditions
❱
- 75.2.1. Example: u8 to bool
- 75.3. Determining preconditions
❱
- 75.3.1. Example: references
- 75.4. Defining your own preconditions
❱
- 75.4.1. Example: ASCII Type
- 76. Rules of the game
❱
- 76.1. Rust is sound
- 76.2. Copying memory
❱
- 76.2.1. Safe Rust
- 76.2.2. Encapsulated Unsafe Rust
- 76.2.3. Exposed Unsafe Rust
- 76.2.4. Documented safety preconditions
- 76.2.5. Crying Wolf
- 76.3. 3 shapes of sound Rust
- 76.4. Soundness Proof
❱
- 76.4.1. Soundness
- 76.4.2. Corollary
- 76.4.3. Unsoundness
- 77. Memory Lifecycle
- 78. Initialization
❱
- 78.1. MaybeUninit
❱
- 78.1.1. Arrays of uninit
- 78.1.2. MaybeUninit::zeroed()
- 78.1.3. ptr::write vs assignment
- 78.2. How to initialize memory
- 78.3. Partial initialization
- 79. Pinning
❱
- 79.1. What pinning is
- 79.2. What a move is
- 79.3. Definition of Pin
- 79.4. Why it's difficult
- 79.5. Unpin trait
- 79.6. PhantomPinned
- 79.7. Self-Referential Buffer Example
❱
- 79.7.1. C++ implementation
- 79.7.2. Modeled in Rust
❱
- 79.7.2.1. With a raw pointer
- 79.7.2.2. With an integer offset
- 79.7.2.3. With Pin<Ptr>
- 79.8. Pin<Ptr> and Drop
❱
- 79.8.1. Worked Example
- 80. FFI
❱
- 80.1. Language Interop
- 80.2. Strategies
- 80.3. Consideration: Type Safety
- 80.4. Language differences
❱
- 80.4.1. Different representations
- 80.4.2. Different semantics
- 80.4.3. Rust ↔ C
- 80.4.4. C++ ↔ C
- 80.4.5. Rust ↔ C++
- 80.5. abs(3)
- 80.6. rand(3)
- 80.7. Exercise:C library
- 80.8. Exercise: C++ library
- Final Words
- 81. Thanks!
- 82. Glossary
- 83. Other Resources
- 84. Credits