Rust Cookbook

repository·master·Indexed 25 days ago

https://github.com/rust-lang-nursery/rust-cookbook

A collection of complete, tested Rust examples demonstrating best practices for common programming tasks using the Rust ecosystem. The repository includes implementations for randomness, bzip2 compression, the Actor pattern, custom Future implementations, and various CLI tools, designed to be easily integrated into new Cargo projects.

Tokens
140.3K
Snippets
325
Records
525
Agent score
82%

What's inside rust-cookbook

  1. Networking Recipes Overview

    master

    The Networking section of the Rust Cookbook provides recipes for common network programming tasks using the standard library (std).

    Available recipes include:

    TCP/IP

    • Listen on an unused TCP/IP port
    • Implement a TCP echo server
    • Implement a TCP client
    • Connect to a TCP address with a timeout
    • Set a read timeout on a TCP stream
    • Disable Nagle's algorithm (nodelay)
    • Half-close a TCP connection
    • Perform non-blocking TCP accept

    UDP

    • Send and receive UDP datagrams
    • Join a UDP multicast group

    IP Addresses and Hostnames

    • Resolve a hostname to socket addresses
    • Classify an IP address
    • Bind for both IPv4 and IPv6 (dual stack)
  2. File System Recipes Overview

    master
    The File System section of the Rust Cookbook provides various recipes for common filesystem tasks. These recipes cover reading/writing files, directory traversal, pattern matching, and watching for file changes. Many recipes utilize the standard library (std), while others use specialized crates like tempfile, walkdir, glob, notify, or memmap.
  3. Available WebAssembly embedding recipes

    master

    The following recipes demonstrate how to use the wasmtime host embedding API for various tasks:

    • Call an exported WebAssembly function: How to load modules and invoke their exported functions.
    • Exchange data via WebAssembly linear memory: How to share and manipulate linear memory between the host and the guest.
    • Define host functions for WebAssembly: How to wire up host-defined functions that WebAssembly guests can call back into.
    • Component Model — typed strings and structs: Using the WebAssembly Component Model to handle typed data like strings and structs (requires wasmtime and wit-bindgen).
  4. Database Recipes Overview

    master

    The Rust Cookbook provides several recipes for working with databases using different crates and drivers. You can find specific implementations for SQLite, Postgres, SQLx, and SeaORM.

    SQLite (using rusqlite)

    • Create a SQLite database
    • Insert and Query data

    Postgres (using postgres)

    • Create tables in a Postgres database
    • Insert and Query data
    • Aggregate data

    SQLx (Async SQL toolkit)

    • Connect to SQLite pool and simple query
    • Connect to Pg Pool and query typed rows
    • Compile-time checked queries
    • Transactions in SQLx

    SeaORM (Async ORM)

    • Simple ORM pattern
  5. Concurrency Recipes Overview

    master

    The Concurrency section of the Rust Cookbook provides various recipes for managing parallel and concurrent execution. These are categorized into several implementation patterns:

    Threading & Pipelines

    • Crossbeam: Spawning short-lived threads, creating parallel data pipelines, and passing data between two threads (SPSC).
    • Thread Pools: Calculating SHA1 sums of files concurrently, summing directory file sizes, and dispatching fractal drawing work to a thread pool.
    • Global State: Maintaining global mutable state using lazy_static.

    Synchronization Primitives

    • Atomics: Implementing lock-free counters with AtomicUsize.
    • Shared State: Guarding compound state with Arc<Mutex<T>> or allowing concurrent reads with Arc<RwLock<T>>.
    • Communication & Coordination: Using mpsc channels for thread communication, Barrier for coordinating thread phases, and Condvar for signaling waiting threads.

    Data Parallelism with Rayon

    • Parallel Iteration: Mutating array elements in parallel, testing predicates (any/all) in parallel, and searching items in parallel.
    • Parallel Algorithms: Sorting vectors, performing map-reduce operations, and generating JPG thumbnails in parallel.

    Async & Patterns

    • Actor Pattern: Implementing the Actor pattern using Tokio.
    • Custom Futures: Implementing a custom Future using Pin, Waker, and Poll.
  6. HTTP Client Recipes using Reqwest

    master

    The Rust Cookbook provides several recipes for interacting with HTTP clients, primarily using the reqwest crate. These recipes cover common networking tasks including:

    • Basic Requests: Making HTTP GET requests.
    • RESTful Operations: Setting custom headers, using URL parameters, checking if resources exist (HEAD requests), and performing POST/DELETE operations (e.g., interacting with the GitHub API).
    • Pagination: Consuming paginated RESTful APIs.
    • File Operations: Downloading files to temporary directories, performing partial downloads using HTTP range headers, and POSTing files to services like paste-rs.
  7. Explore Mathematics recipes in the Rust Cookbook

    master

    The Rust Cookbook provides several recipes for scientific and mathematical computations. These are categorized by sub-topic and the crates used to implement them.

    Linear Algebra

    Recipes using ndarray or nalgebra:

    • Vector Norm: Calculate the norm of a vector.
    • Adding matrices: Perform matrix addition.
    • Multiplying matrices: Perform matrix multiplication.
    • Multiply a scalar with a vector with a matrix: Combined scalar-vector-matrix operations.
    • Invert matrix: Invert a matrix using nalgebra.

    Trigonometry

    Recipes using the Rust standard library (std):

    • Calculating the side length of a triangle
    • Verifying tan is equal to sin divided by cos
    • Distance between two points on the Earth (using latitude and longitude)

    Complex Numbers

    Recipes using the num crate:

    • Creating complex numbers
    • Adding complex numbers
    • Mathematical functions on complex numbers

    Statistics

    Recipes using the Rust standard library (std):

    • Measures of central tendency
    • Computing standard deviation

    Miscellaneous

    • Big integers: Using the num crate for large integer arithmetic.
  8. Asynchronous Recipes Overview

    master

    The Rust Cookbook provides several recipes for working with asynchronous programming, primarily utilizing the tokio crate. Key topics covered include:

    • Runtime Management: Using the tokio runtime macro or the Runtime Builder approach.
    • File Operations: Asynchronous creation, reading, writing, and removal of files and directories, as well as working with AsyncRead and AsyncWrite traits.
    • Channels: Implementing communication using both bounded and unbounded channels.
    • Concurrency Control: Managing tasks using First-to-complete patterns, Task Timeouts, and Join Sets.
  9. Create a SQLite database with rusqlite

    master

    Use the rusqlite crate to manage SQLite databases. The Connection::open method can be used to open an existing database or create a new one if the specified file does not already exist. Once a connection is established, you can use conn.execute to run SQL commands such as CREATE TABLE to initialize your schema.

    use rusqlite::{Connection, Result};
    
    fn main() -> Result<()> {
        let conn = Connection::open("cats.db")?;
    
        conn.execute(
            "create table if not exists cat_colors (
                 id integer primary key,
                 name text not null unique
             )",
            (),
        )?;
        conn.execute(
            "create table if not exists cats (
                 id integer primary key,
                 name text not null,
                 color_id integer not null references cat_colors(id)
             )",
            (),
        )?;
    
        Ok(())
    }
  10. Enable log levels per module using RUST_LOG

    master

    You can control logging verbosity for specific modules using the RUST_LOG environment variable when using env_logger. Module declarations follow the format path::to::module=log_level, where entries are comma-separated. This allows you to set a global default level and override it for specific sub-modules or crates.

    RUST_LOG="warn,test::foo=info,test::foo::bar=debug" ./test
  11. Use transactions with rusqlite

    master

    To manage atomic operations in SQLite using rusqlite, use Connection::transaction to begin a transaction. Transactions in rusqlite follow a rollback-by-default pattern: if the Transaction object is dropped without calling Transaction::commit, all changes made during the transaction will be rolled back. To persist changes, you must explicitly call tx.commit().

    use rusqlite::{Connection, Result};
    
    fn main() -> Result<()> {
        let mut conn = Connection::open("cats.db")?;
    
        successful_tx(&mut conn)?;
    
        let res = rolled_back_tx(&mut conn);
        assert!(res.is_err());
    
        Ok(())
    }
    
    fn successful_tx(conn: &mut Connection) -> Result<()> {
        let tx = conn.transaction()?;
    
        tx.execute("delete from cat_colors", [])?;
        tx.execute("insert into cat_colors (name) values (?1)", ["lavender"])?;
        tx.execute("insert into cat_colors (name) values (?1)", ["blue"])?;
    
        tx.commit()
    }
    
    fn rolled_back_tx(conn: &mut Connection) -> Result<()> {
        let tx = conn.transaction()?;
    
        tx.execute("delete from cat_colors", [])?;
        tx.execute("insert into cat_colors (name) values (?1)", ["lavender"])?;
        tx.execute("insert into cat_colors (name) values (?1)", ["blue"])?;
        tx.execute("insert into cat_colors (name) values (?1)", ["lavender"])?;
    
        tx.commit()
    }
  12. Create, query, and update rows with SeaORM

    master

    To implement a simple ORM pattern using SeaORM, follow these steps:

    1. Connect to a database: Use Database::connect to establish a connection (e.g., an in-memory SQLite database).
    2. Initialize schema: Use Schema::create_table_from_entity to generate and create a table based on a SeaORM entity.
    3. Create rows: Instantiate an ActiveModel and use ActiveModelTrait::save to persist it to the database.
    4. Query rows: Use EntityTrait::find to load existing records from the database.
    5. Update rows: Modify the fields of an ActiveModel and call ActiveModelTrait::save again. The method returns the updated model, allowing you to verify the saved values.