Rust Cheatsheet
Written
— Updated
- Asynchronous Rust
- Asynchronous Closures
- You can define code blocks as
async
, just like you can with functions. You'll usually need to usemove
on the code block as well. the_function.await?;
- You can define code blocks as
- Taking Asynchronous Closure Arguments
- It starts like usual, with an
Fn
,FnOnce
, orFnMut
trait boundary, but you have to define the return type and you can't doimpl Future
in the trait. - The way around this is to define another type parameter, and put the trait boundary on that.
async
- It starts like usual, with an
- Dealing with Time
- Periodic Functions
- For loops that need to run periodically, normally you would use
sleep
to wait for the next call. - But Tokio provides an
interval
object which accounts for the time that the call actually took. So your 500ms periodic poll will actually run every 500ms, instead of 500ms + some random amount. - The first call to
interval.tick()
will trigger right away. You can useinterval_at
instead if this is undesirable, but generally it just means you move the wait part of the loop to the top.
- For loops that need to run periodically, normally you would use
- Timeouts
tokio::time::timeout(duration, operation())
is an easier way to do a timeout than usingselect!
with a sleep.
- Periodic Functions
- Asynchronous Closures
- Inner Arc Pattern
- For types that you want to always be clonable and within an
Arc
without needing to deal with the Arc everywhere, you can make an outer NewType that just contains anArc<InnerType>
. - In this case you do have to implement Clone manually for things to really work properly. But it's pretty easy.
; // Implement methods on the outer type, which access the inner type.
- This pattern should only be used for types that you know will be passed around between threads or async contexts, such as connection pools. Otherwise it's usually better to let the user of your library add an
Arc
if needed.
- For types that you want to always be clonable and within an
- Partial Moves
- Rust doesn't allow moving part of a structure out, but there are better ways than just
clone
. - Use
mem::replace
to take items out from structures without needing to take ownership of the entire thing. - Destructuring also helps when you want to eventually move all the items out of the structure.
- Lately I've been just destructuring more and more.
- Rust doesn't allow moving part of a structure out, but there are better ways than just
- Serde
- To enable auto-derive of Serialize and Deserialize traits, the best way is to enable the
derive
feature in theserde
crate. You can also just include theserde-derive
crate manually.
- To enable auto-derive of Serialize and Deserialize traits, the best way is to enable the
- Performance
fxhash
crate is good for fast hashing that doesn't need to be cryptographically secure.- Rust Performance Book
- Enable Link-time Optimization
lto = true
- Tracing Level Format
tracing_subscriber::EnvFilter
takes the formattarget[span{field=value}]=level
- All except for
level
are optional. value
, if present, acts as a regex unless it's a number or boolean. As a string, it should be surrounded by quotes. If absent, then it just filters on the presence offield
.- If exporting to GRPC with HTTPS, you need to make sure that the tonic crate has the
tls-roots
feature enabled. Otherwise you'll get a HTTP/2 "frame with invalid size" error, which is not very helpful for figuring out the issue.