Get ready to code like a pro in Rust! This hands-on guide dives deep into memory management, asynchronous programming, and Rust design patterns and explores essential productivity techniques like testing, tooling, and project management.
Get ready to code like a pro in Rust! This hands-on guide dives deep into memory management, asynchronous programming, and Rust design patterns and explores essential productivity techniques like testing, tooling, and project management.
Code Like A Pro in Rust is a fast-track guide to building and delivering professional quality software in Rust. You’ll upgrade your basic knowledge of Rust with conventions, best practices, and veteran’s secrets that are normally only learned through years of experience. Skip the fluff and get right to the heart of this powerful modern language, including Rust’s support for asynchronous programming and integrating Rust with codebases written in other languages.
Purchase of the print book includes a free eBook in PDF, Kindle, and ePub formats from Manning Publications.
Author(s): Brenden Matthews
Edition: MEAP 9
Publisher: Manning Publications
Year: 2022
Language: English
Pages: 225
Code Like a Pro in Rust MEAP V09
Copyright
Welcome
Brief contents
Chapter 1: Feelin' Rusty
1.1 What’s Rust?
1.2 What’s unique about Rust?
1.2.1 Rust is safe
1.2.2 Rust is modern
1.2.3 Rust is pure open source
1.2.4 Rust versus other popular languages
1.3 When should you use Rust?
1.3.1 Rust use cases
1.3.2 Tools you’ll need
1.4 Summary
Chapter 2: Project management with Cargo
2.1 Cargo tour
2.1.1 Basic usage
2.1.2 Creating a new application or library
2.1.3 Building, running, and testing
2.1.4 Switching between toolchains
2.2 Dependency management
2.2.1 Handling the Cargo.lock file
2.3 Feature flags
2.4 Patching dependencies
2.4.1 Indirect dependencies
2.4.2 Best practices with dependency patching
2.5 Publishing crates
2.5.1 CI/CD integration
2.6 Linking to C libraries
2.7 Binary distribution
2.7.1 Cross compilation
2.7.2 Building statically linked binaries
2.8 Documenting Rust projects
2.8.1 Code examples in documentation
2.9 Modules
2.10 Workspaces
2.11 Custom build scripts
2.12 Rust projects in embedded environments
2.12.1 Memory allocation
2.13 Summary
Chapter 3: Rust tooling
3.1 Overview of Rust tooling
3.2 Using rust-analyzer for Rust IDE integration
3.2.1 Magic completions
3.3 Using rustfmt to keep code tidy
3.3.1 Installing rustfmt
3.3.2 Configuring rustfmt
3.4 Using Clippy to improve code quality
3.4.1 Installing Clippy
3.4.2 Clippy’s lints
3.4.3 Configuring Clippy
3.4.4 Automatically applying Clippy’s suggestions
3.4.5 Using Clippy in CI/CD
3.5 Reducing compile times with sccache
3.5.1 Installing sccache
3.5.2 Configuring sccache
3.6 Integration with IDEs, including VS Code
3.7 Using toolchains: stable vs nightly
3.7.1 Nightly-only features
3.7.2 Using nightly on published crates
3.8 Additional tools: cargo-update, cargo-expand, cargo-fuzz, cargo-watch, cargo-tree
3.8.1 Keeping packages update to date cargo-update
3.8.2 Debugging macros with cargo-expand
3.8.3 Testing with cargo-fuzz
3.8.4 Iterating with cargo-watch
3.8.5 Examining dependencies with cargo-tree
3.9 Summary
Chapter 4: Data structures
4.1 Demystifying String, str, &str, and &'static str
4.1.1 String vs str
4.1.2 Using strings effectively
4.2 Understanding slices and arrays
4.3 Vectors
4.3.1 Diving deeper into Vec
4.3.2 Wrapping vectors
4.3.3 Types related to vectors
4.4 Maps
4.4.1 Custom hashing functions
4.4.2 Creating hashable types
4.5 Rust types: primitives, structs, enums, aliases
4.5.1 Using primitive types
4.5.2 Using tuples
4.5.3 Using enums
4.5.4 Using aliases
4.6 Error handling with Result
4.7 Converting types with From/Into
4.7.1 TryFrom and TryInto
4.7.2 Best practices for type conversion using From and Into
4.8 Handling FFI compatibility with Rust’s types
4.9 Summary
Chapter 5: Working with memory
5.1 Memory management: heap and stack
5.2 Understanding ownership: copies, borrowing, references, and moves
5.3 Deep copying
5.4 Avoiding copies
5.5 To box or not to box: smart pointers
5.6 Reference counting
5.7 Clone on write
5.8 Custom allocators
5.8.1 Writing a custom allocator
5.8.2 Creating a custom allocator for protected memory
5.9 Summary
Chapter 6: Unit testing
6.1 How testing is different in Rust
6.2 Review of built-in testing features
6.3 Testing frameworks
6.4 What not to test, or why the compiler knows better than you
6.5 Handling parallel test special cases and global state
6.6 Thinking about refactoring
6.7 Refactoring tools
6.7.1 Reformating
6.7.2 Renaming
6.7.3 Relocating
6.7.4 Rewriting
6.8 Code coverage
6.9 Dealing with a changing ecosystem
6.10 Summary
Chapter 7: Integration testing
7.1 Comparing integration and unit testing
7.2 Integration testing strategies
7.3 Built-in integration testing versus external integration testing
7.4 Integration testing libraries and tooling
7.4.1 Using assert_cmd to test CLI applications
7.4.2 Using proptest with integration tests
7.4.3 Other integration testing tools
7.5 Fuzz testing
7.6 Summary
Chapter 8: Design pattern building blocks
8.1 Generics
8.1.1 Basics of generics
8.1.2 Exploring Option
8.1.3 Generic parameter trait bounds
8.2 Traits
8.2.1 What’s in a trait?
8.2.2 Understanding traits by examining object-oriented code
8.2.3 Combining generics and traits
8.2.4 Deriving traits automatically
8.2.5 Trait objects
8.3 Pattern matching
8.3.1 Basics of pattern matching
8.3.2 Clean matches with the ? operator
8.4 Functional programming patterns
8.4.1 Basics of FP in Rust
8.4.2 Closure variable capture
8.4.3 Examining iterators
8.4.4 Iterator features
8.5 Summary
Chapter 9: Design patterns: beyond the basics
9.1 Metaprogramming with macros
9.1.1 A basic declarative macro in Rust
9.1.2 When to use macros
9.1.3 Using macros to write mini-DSLs
9.1.4 Using macros for DRY (don’t repeat yourself)
9.2 Optional function arguments
9.2.1 Emulating optional arguments with traits
9.3 Builder pattern
9.3.1 Implementing the builder pattern
9.3.2 Enhancing our builder with traits
9.3.3 Enhancing our builder with macros
9.4 Fluent interfaces
9.4.1 A fluent builder
9.4.2 Test driving our fluent builder
9.5 Observer pattern
9.5.1 Why not callbacks?
9.5.2 Implementing an observer
9.6 Rust library ergonomics and patterns
9.6.1 Revisiting linked lists
9.6.2 Using rustdoc to improve our API design
9.6.3 Improving our linked list with more tests
9.6.4 Making our library easier for others to debug
9.7 Summary
Chapter 10: Advanced design patterns
10.1 Const generics
10.2 Implementing traits for external crate types
10.3 Blanket traits
10.4 Marker traits
10.5 Struct tagging
10.6 Trait state machine
10.7 Procedural macros
10.8 Preludes
10.9 Summary
Chapter 11: Async Rust
11.1 Runtimes
11.2 Thinking asynchronously
11.3 Futures: handling async task results
11.3.1 Defining a runtime with #[tokio::main]
11.4 async & .await: when and where
11.5 Concurrency & parallelism with async
11.6 Implementing an async observer
11.7 Mixing sync and async
11.8 When not to use async
11.9 Tracing and debugging async code
11.10 Dealing with async when testing
11.11 Summary
Chapter 12: Optimizations
12.1 Zero cost abstractions
12.2 Vectors
12.2.1 Vector memory allocation
12.2.2 Vector iterators
12.2.3 Fast copies with Vec and slices
12.3 SIMD
12.4 Parallelization with rayon
12.5 Using Rust to accelerate other languages
12.6 Where to go from here
12.7 Summary
Appendix A: Installing tools for this book
A.1 Installing tools on macOS using Homebrew
A.2 Installing tools on Linux systems
A.2.1 On Debian-based systems:
A.2.2 On Red Hat-based systems:
A.3 Installing rustup on Linux or UNIX-based systems
A.4 Installing tools on Windows
A.5 Managing rustc and other Rust components with rustup
A.5.1 Installing rustc and other components
A.5.2 Switching default toolchains with rustup
A.5.3 Updating Rust components
Notes