Rust Rustcamp

repository·master·Indexed 20 days ago

https://github.com/rust-lang-ua/rustcamp

A structured certification program for developers to become proficient Rust programmers. The curriculum includes foundational vocabulary on memory models and type systems, hands-on tasks covering traits (Default, Clone, Copy), smart pointers (Box, Rc, Arc), pinning (Pin, Unpin), and interior mutability (Cell, RefCell, Mutex, RwLock).

Tokens
35.4K
Snippets
74
Records
176
Agent score
68%

What's inside rust-lang-ua-rustcamp

  1. Overview of Rust Rustcamp

    master
    Rust Rustcamp is a rigorous, step-by-step Rust certification program designed to train developers to a Strong Junior level (or Middle-level for those transitioning from other languages). The program involves small group meetings, daily skill enhancement, a capstone project, and a final comprehensive assessment to earn a certificate.
  2. Database migration and external web service integration guide

    master

    This chapter covers essential patterns for managing database schema evolution and handling external dependencies in a Rust application. Specifically, it addresses:

    • Database Migrations: Using sqlx to manage and execute SQL migrations.
    • Integration Testing: Preparing and managing database state for reliable integration tests.
    • Mocking External Services: Strategies and crates for mocking external REST services to ensure tests are isolated and deterministic.
  3. Explore the Rustcamp Curriculum and Tasks

    master

    The Rustcamp curriculum is organized into several progressive tasks covering core concepts, idioms, the ecosystem, backend development, and a capstone project.

    Curriculum Structure:

    • Task 0: Vocabulary
    • Task 1: Concepts (e.g., Default values, Boxing/Pinning, Shared ownership, Clone-on-write, Conversions, Static/Dynamic dispatch, Sized types, Thread safety, Phantom types)
    • Task 2: Idioms (e.g., Type safety, Mem replace, Bound impl, Generic in/out, Exhaustivity, Sealing)
    • Task 3: Ecosystem (e.g., Testing, Macros, Date/Time, Regex, Collections, Serde, Rand/Crypto, Logging, Cmd/Env/Conf, Threads, Async)
    • Task 4: Backend (e.g., DB, HTTP, API, gRPC)
    • Task 5: Zero2Prod (Chapters based on the Zero To Production in Rust book)
    • Task 6: Project (Capstone project implementation, reviews, and presentation)
  4. Authentication & Authorization Concepts

    master

    This section covers the fundamental security requirements for building web applications, specifically focusing on:

    • Auth Best Practices: Implementing industry-standard security patterns.
    • JWT (JSON Web Tokens): Understanding what they are, how to use them for stateless authentication, and identifying Rust crates that implement the JWT standard.
    • Password Security: Techniques for securely storing passwords in a database (e.g., using hashing algorithms rather than plain text).
    • Actix-web Integration: How to apply authentication and authorization logic to actix-web routes to protect specific endpoints.
  5. Understand Async I/O, Futures, and Actors in Rust

    master

    This task covers the fundamental concepts of asynchronous programming in Rust. To master this section, you should be able to explain and understand the following core topics:

    Core Concepts

    • Asynchronous Programming: How it relates to multithreading and the specific problems it solves.
    • Non-blocking I/O: How it differs from blocking I/O and how it functions.
    • The Future Trait: Its purpose, how it works in Rust, its zero-cost semantics, and how it differs from futures in other languages.
    • async/.await Syntax: How these keywords desugar into Futures and why they are necessary for ergonomics.
    • Tasks vs. Futures: The distinction between an asynchronous task and a Future.
    • The Waker: Its role, how it works, and why it is required for the async lifecycle.
    • Asynchronous Runtimes: What they are, their typical components, and the different types of runtimes (e.g., regarding multithreading).
    • Multitasking Models: The type of multitasking represented by Rust Futures (cooperative multitasking) and its trade-offs.
    • Blocking the Runtime: Why blocking an async runtime is detrimental and how to avoid it in practice.
    • The Actor Model: Key points of the actor model concurrency paradigm and its utility in Rust.

    When implementing these concepts, you will likely interact with these libraries:

    • Runtimes: tokio, async-std, actix-rt, glommio.
    • Utilities: futures, futures-lite, async-trait.
    • Actor Frameworks: actix, riker, quickwit-actors, bastion.
  6. What is a sealed trait in Rust and why use it?

    master

    A sealed trait is a publicly accessible trait that cannot be implemented outside its definition place (the specific module or crate).

    Purpose: Future-proofing APIs

    Sealing allows library authors to evolve their API without breaking downstream code. Because you control all possible implementations, you can safely:

    • Add new methods to the trait in a non-breaking release.
    • Change the signatures of methods that are not publicly documented (e.g., those marked with #[doc(hidden)]).

    How it works

    Sealing relies on tricking Rust's visibility rules. By making the trait require a supertrait that is not publicly exported, you ensure that no code outside your crate can satisfy the requirement to implement the main trait. It does not change the type system's semantics; it is a visibility-based restriction.

  7. Understand Boxing in Rust

    master

    Box<T> is a smart pointer that owns heap-allocated data. It is used to:

    1. Avoid lifetime complexity: Instead of using references (&T or &mut T) which require managing lifetimes, Box provides ownership of heap data.
    2. Handle fixed-size slices: Box<str> or Box<[T]> can be used when an owned slice is needed but the size is not intended to be resized (unlike String or Vec<T>).
    3. Indirection: It allows for recursive types or types where the size must be known at compile time but the data lives on the heap.
    // Example of using Box for heap allocation
    let x = Box::new(5); // 5 is now on the heap
    let s: Box<str> = "hello".into(); // Fixed-size heap string
  8. Synchronize threads using atomics, shared state, or channels

    master

    Thread synchronization in Rust is achieved through three primary patterns:

    1. Atomic Operations: Low-level synchronization using the std::sync::atomic module (or the atomic crate).
    2. Shared State with Exclusive Access: Controlling access to shared data using primitives from the std::sync module (e.g., Mutexes).
    3. Thread Communication: Passing data between threads using channels, implemented in the std::sync::mpsc module.

    For more optimized or feature-rich synchronization, the crossbeam crate (specifically crossbeam-channel) is a highly recommended enhancement over the standard library's MPSC implementation.

  9. Distinguish between AsRef/AsMut and Borrow/BorrowMut

    master

    Both sets of traits have similar signatures, but they serve different semantic purposes:

    • AsRef / AsMut: Used when a type can be represented as a reference to another type (e.g., one type contains another). It is more flexible and can be implemented even if the types are not semantically identical.
    • Borrow / BorrowMut: Used when the implementor type is semantically equivalent to the implemented type, differing only in storage. Crucially, Borrow requires that Hash, Eq, and Ord implementations for the borrowed value are identical to those of the owned value.

    When to use which:

    • Use Borrow<T> when generic code relies on identical behavior (like Eq or Hash) between owned and borrowed versions.
    • Use AsRef<T> when you simply need to work with any type that can provide a reference to a related type.
  10. Achieve exhaustiveness checking with Enums

    master

    To ensure your code breaks at compile-time whenever a new enum variant is added, avoid using the wildcard pattern _ or match-anything bindings in match expressions. By explicitly listing every variant, the compiler will signal an error if a new variant is introduced but not handled, preventing logic bugs (like incorrect permission assignments).

    // BAD: Using wildcard `_` prevents compile-time errors when new roles are added
    fn grant_permissions(role: &Role) -> Permissions {
        match role {
            Role::Reporter => Permissions::Read,
            Role::Developer => Permissions::Read & Permissions::Edit,
            _ => Permissions::All, 
        }
    }
    
    // GOOD: Explicitly matching all variants ensures compile-time safety
    fn grant_permissions(role: &Role) -> Permissions {
        match role {
            Role::Reporter => Permissions::Read,
            Role::Developer => Permissions::Read & Permissions::Edit,
            Role::Admin => Permissions::All, 
        }
    }
  11. Manage Hierarchical Configuration with the `config` crate

    master

    The config crate allows you to create hierarchical, typed configuration structures following 12-factor app principles. It enables merging configuration from multiple sources in a specific order.

    Supported sources include:

    • Environment variables
    • String literals (various formats)
    • Other Config instances
    • Files: TOML, JSON, YAML, INI, RON, JSON5, and custom formats via the Format trait
    • Manual programmatic overrides via the .set method

    Key features include live watching/re-reading of files, deep access via path syntax, and serde deserialization.