Rust has a slim standard library. It provides many core types such as vectors and strings, abstractions the ecosystem builds on. You will not, however find random numbers or time and date in the standard library. Luckily anything you might miss has long been filled in by the community. Innovative new crates (third party libraries) also pop up for problems usually solved in the standard library. The slimness removes the standard library as competitor for these crates, lowering the bar to the spotlight. The downside is that we can’t just take the standard libraries' solution but need to figure out, which crate provides what we need.
Here are the crates I rely on:
Errors
In Rust its customary for your errors to be types that allow pattern matching when writing a library. Normally you accomplish by representing your errors as variants of an enum
. The crate thiserror helps you to make the enum convenient to use. When writing an application however, you match on errors, handling them or reporting them. I use eyre
to build beautiful error reports that give a useful backtrace.
-
For libraries: thiserror
-
For applications: color-eyre most documentation lives here
-
To check/prove a function can’t crash your program: no-panic
Logging
You are probably familiar with backtraces, often shown as a list of functions your program entered to get to a point where it crashed. Tracing gives you on demand ‘backtraces’ without crashing. It can include the parameters for all the called functions. The traces can be inspected by hand (from a log file) or using tools such as jeager. Right now tracing can still be a bit of a hassle to set up. For simple applications you might want to use log with simplelog.
- Simple applications: log + simplelog
hint: use add_filter_ignore to stop verbose dependencies from flooding the log (useful at low log levels). - Complex systems: tracing also provides (structured) logging
Tests
- checking float equality: float_eq
basic usage:assert_float_eq!(a, b, ulps <= 1)
for more see: docs - temporary dirs and files: tempfile
Command Line
- Argument parsers: clap
Runtime
- Async runtime: tokio
- Macros and functions making async easier: futures
- Trait making future composition way easier (replaces
select!
): futures-concurrency
Meant for staging/experimentation. Its perfectly usable however and I can not live without.
Web
- Http client: reqwest (async, optionally blocking)
- Http server: actix-web (async)
- HTML templating: yarte
- Remote procedure calls: tarpc (async)
Data
- High performance embedded database: sled
- Concurrent hashmap: dashmap
- Lock free eventually consistent map evmap
- Serialization and deserialization to many formats: serde. You use serde together with a crate that specifies a format to serialize to/from any rust type. See this list of the formats.
Gui
Other
Standard lib expansion
- Bounded queue: crossbeam-channel
- Derive traits: derivative
- Iterators: itertools
Embedded
- Async runtime: embassy
You will need to use a git dependency as embassy is still early in development. Do not forget to add a
rev
key with a specific commit hash to theCargo.toml
entry to ensure reproducable builds. - Efficient logging: defmt
- Hardware abstraction: embedded-hal
- Global variables: lazy_static