Rust Resources

Written — Updated
  • Awesome Rust
  • Rust Design Patterns
  • https://lib.rs/ is great for browsing for crates for a specific purpose or just for fun
  • https://docs.rs/CRATE_NAME for docs for any public crate.
  • Crates
    • Asynchronous Code
      • tokio, async_std, and futures are the base crates. Tokio and Async_std are sort of "competing" and there's still a lot of similar-but-slightly-different versions of core traits like AsyncRead between them.
      • tokio-util has a lot of nice adaptors and things that makes it easier to work with streams, readers, writers, etc.
    • Performance and Data Processing
      • rayon for super-easy parallelism
      • itertools adds a bunch of useful functions that work with Iterator
      • ahash is a good default hash replacement.
        • It is not cryptographically secure. But unlike many non-cryptographically secure hashes, it is designed to be DOS resistant, so it's OK to use it for HashMaps that take user-provided input.
        • ahash also uses a random seed initialization and is not guaranteed to have stable output across versions or platforms, so you generally should not use it in situations where a hash will be stored to disk or sent across the network, but it is great for in-memory data structures.
      • smallvec when you are making a lot of mostly-small vectors and most, but not all of them, will be below a certain size.
      • arrayvec when you are making a lot of small vectors and know that they will never exceed a certain size
      • aho-corasick for performing multiple substring searches at once in a larger string
    • Error Handling
      • error-stack makes it easy to retain the entire stack of errors throughout execution, ensuring nothing is lost. It also allows attaching additional context to any error in the stack.
        • This isn't a replacement for thiserror, but a great complement to it, and I use it in all my projects now.
      • anyhow is great for just merging random errors together when you don't really care otherwise and just want to get the error message out and all the various errors to have the same type. (i.e. most CLI utilities)
      • eyre is a fork of anyhow with emphasis on better error reporting
        • color-eyre works with eyre for much nicer error reporting
      • thiserror is nice for structured error types where you want to add extra formatting or otherwise handle errors in a more detailed way.
        • Can wrap an anyhow inside a thiserror as well
        • #[derive(Error, Debug)]
          pub enum RequestError {
            #[error("Invalid query string: {0}")]
            QueryStringError(#[from] serde_qs::Error),
          
            #[error(transparent)]
            Other(#[from] anyhow::Error),
          }
          
    • Argument Parsing
      • clap lets you define command-line arguments declaratively, with options and subcommands.
        • #[derive(Debug, Parser)]
          #[clap(name="myapp")]
          struct Args {
            // Can add `default` and a bunch of other things as well
            #[clap(long="file", short="f", help="")]
            file: PathBuf,
          
            // Can use long and short without values to get the "obvious" defaults
            /// Help text can go in a doc comment like this too
            #[clap(long, short)]
            tag: Option<String>,
          
            // default_value
            #[clap(long="count", short="c", default_value_t=5)]
            count: u32,
          
            // array of arguments
            #[clap(long, short)]
            values: Vec<String>,
          }
          
          
    • CLI
    • Database
      • sqlx for connecting to a database and running queries.
        • Contains connection pools, migration support and all that.
        • You can derive sqlx::FromRow on structs to read query results into a structure.
        • Derive sqlx::Type on enums to translate them to strings (or Postgres types)
        • Supports a bunch of different async runtimes and all the popular SQL databases.
        • Supports compile-time query validation and result type generation with the query! macro. Or query_as! to use an existing type.
      • diesel for a full-fledged ORM if that's your style. I've been using this recently and it's nice, with the usual caveats around having to fall back to raw SQL to do more complex queries. (See Diesel Rust ORM)
      • sea_orm is another up-and-coming ORM, built on async and with more attempt to provide database-agnostic behavior at runtime.
    • Image Handling
      • image for general image loading and running filters
      • pix is another option. Haven't tried it though.
        • It works with footile to do plotter-style image manipulation
      • ab_glyph and glyph_brush_layout for text rendering
      • resvg for rendering SVG, and usvg for parsing SVG source
      • tiny-skia for drawing. resvg uses this internally
    • Miscellaneous
      • nom for building parsers
      • katex for rendering LaTeX
      • aarc-rs/aarc: Atomically updatable variants of Arc and Weak for lock-free concurrency.
      • syntect for syntax highlighting
        • I've heard that tree-sitter is good for this too but haven't tried it.
      • handlebars, liquid, and tera are popular libraries for text templates. I'm currently mostly using tera since it supports template inheritance but they're all good.
      • opendal and object_store for abstracting IO operations over different storage such as local disk and various cloud storage services.
      • delegate for delegating method calls to the same method on an internal field.
      • ouroboros and self_cell for allowing members of a structure to reference other owned members in the structure, with some additional methods to build and borrow the data.
      • tempfile for managing temporary files that will automatically clean themselves up
      • strum includes a bunch of functionality for enums such as iterating over the members and autogenerating a Display impl.
      • Arena Allocators
        • bumpalo skips calling Drop but allows mixed types of allocations in an arena.
        • typed-arena calls Drop but is limited to allocating objects of one type per arena.
      • validator is a derive macro for easily adding validation logic to a struct.
      • typed-builder creates "builder" functionality for a struct
  • Learning
  • Debugging

Thanks for reading! If you have any questions or comments, please send me a note on Twitter.