Skip to content

rust

learn

cheat sheet
comprehensive Rust

install

curl https://sh.rustup.rs -Sfs | sh
-Sfs are show-error/fail/silent options to better deal with scripts

basic

rustc --version
cargo --version
rustup update           # update rust env
cargo new <project>
cargo search <crate>    # to check latest version
cargo build             # build debug (opt-level 0)
cargo build --release   # build release (opt-level 3)

basic concepts

move: aka ownership change; when variable is reassigned or passed to a function
borrow: access a variable via a reference

patterns

unofficial patterns doc

libs

choices:
datetime: chrono
db: sqlx
error: log + env_logger
http server: axum

actix-web (http server)

axum (http server)

diesel.rs (db+ORM)

failure (error)

log + env_logger

reqwest (http client)

sqlx (db)

crates.io 100% Safe Rust (on postgresql). Connection pool. Compile-time checks for queries.
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-native-tls", "macros", "postgres", "json", "time"]}

Runtime-TLS as single feature is deprecated (see 0.6.3 for ex.)
sqlx = { version = "0.6.3", features = ["json", "macros", "postgres", "runtime-tokio-native-tls", "time"] }

Warning

To use macros such as query! need to declare env var DATABASE_URL.
rust-analyser complains if it is not set in .env file

sqlx now in offline mode by default, results of SQL query analysis are cached.
$ cargo sqlx prepare to build and cache schema analysis.

tera (template)

[docs] (https://keats.github.io/tera/)
Inspired by Jinja

thiserror (error)

tips

By default, reqwest's timezone is UTC.

let cnx_options = PgConnectOptions::from_str(&cnx_string)?
    .options([("timezone", "Europe/Paris")]);

tokio (async)

tokio = { version = "1", features = ["macros", "rt-multi-thread"]}

#[tokio::main]
async fn main() {
    ...
}

tracing (trace/log)

misc & tips

closure & async block

sync closure: |var1, var2| { ... }
async closure: async move |var1, var2| { ... }
async block: async move { ... }, compiler moves (or copy when inexpensive, as for pointers) relevant variables (parsing the closure)
One closure advantage: can be used as anonymous fn and reused with different parameter's values.

except vs unwrap

on a Result, unwrap will result value if Ok, or call panic! is Err. except is unwrap with a message
Quality code favours except over unwrap. In some cases, when logic makes sure that Ok will be returned, unwrap might be chosen.

error propagation with ?

? let to be directly returned (kind of raising Exception).
I also allows functions chaining.
For custom errors, don't forget to implement From to have ? benefits (casting to calling function Err type)

global variable

immutable: use static + Lazy
mutable: use Arc + Mutex