Rust toolchain is tightly integrated with documentation and development with cargo.
A trait defines the functionality a particular type has and can share with other types. Struct and Enum are user defined types in Rust. The algebraic type system allows modeling with types and traits that makes code harder to misuse. Think about valid states when modeling.
1
2
3
4
enum IpAddrKind {
V4,
V6,
}
1
2
3
4
5
6
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
Macros are Rust code that writes other Rust code (metaprogramming). Allows
Macros are created using the macro_rules! macro.
1
2
3
4
5
6
7
8
9
10
11
12
macro_rules! say_hello {
// `()` indicates that the macro takes no argument.
() => {
// The macro will expand into the contents of this block.
println!("Hello!")
};
}
fn main() {
// This call will expand into `println!("Hello!")`
say_hello!()
}
Crater compiles and tests every crate. It is used to verify that new versions of Rust are compatible with all crates.
Compiler rustc checks the rules governing memory ownership.
Function std::mem::drop takes ownership of a value and the value is dropped automatically before it returns. The whole function definition is
1
pub fn drop<T>(_x: T) {}
Memory stack is last in first out (LIFO) and faster than the heap. Data with an unknown size at compile time or a size that might change must be stored on the heap.
No garbage collection means no "stop the world" pauses in code execution.
Let the compiler teach usage of lifetimes.
Allows operations that Rust can not guarantee the safety of and limits where to search for memory bugs.
1
rustup update
1
cargo clean --help
Remove a crate with
1
cargo uninstall
Toolchains
1
2
3
rustup toolchain list --help
rustup component list -h
rustup component add rust-analyzer
Other local documentation - books etc.
1
2
3
4
5
rustup doc --path --toolchain stable --clippy
rustup doc --toolchain beta fn
rustup doc --reference
rustup man rustc
rustc --explain E0425
Rust code is packaged as a collection of crates. It's possible to create private package registries.
1
cargo search mask
Cargo honor locked versions, do a reproducible all binaries install.
1
cargo install --bins --locked mask
1
cargo install --list
Show package information with cargo info
Write the dumbest version first, optimise later (for multithreading - tokio, performance, optimal structures, cache etc). Clone data, don't bother with a reference (ignore lifetime issues). Waste RAM to get it working, worry later. Improvements are easy once you got it to compile the first time. Small changes easier.
Think of speed later, use for safety and type system.
cargo testcargo check before to minimize issues on compile. Alternatively, run bacon clippy.1
cargo clippy --fix -- -W clippy::pedantic -W clippy::nursery -W clippy::unwrap_used -W clippy::expect_used
1
rustup doc --rust-by-example
1
cargo install --locked rustlings manrs
Rustlings exercises and the Rust book (The Rust Programming Language, rustup doc --book) are interlinked, Rust By Example is more loosely associated with them.
manrs allows reading the docs without a web browser. Show only examples of I/O
1
manrs -e std::io
A toolchain may become outdated when crates have become a component between updates.
1
2
rustup toolchain uninstall stable
rustup toolchain install stable
Profile is a grouping of components.
1
2
rustup show profile
rustup install --profile minimal beta
The default target architecture for cargo and rustc is the host toolchain's platform.
Toolchain may be overridden on a project basis.
1
2
3
4
5
6
# project_directory/rust-toolchain.toml
[toolchain]
channel = "nightly-2020-07-10"
components = [ "rustfmt", "rustc-dev" ]
targets = [ "arm-linux-androideabi", "thumbv2-none-eabi" ]
profile = "minimal"
The yank command removes a previously published crate's version from the server's index. This command does not delete any data, and the crate will still be available for download via the registry's download link.
Cargo will not use a yanked version for any new project or checkout without a pre-existing lockfile, and will generate an error if there are no longer any compatible versions for your crate.
Suppose bitstream-io version used depends on a yanked crate (deprecated core2), requires a version update.
1
2
cargo update bitstream-io
cargo test
if can do anything but match is type safe, compiler can determine what cases may be missing.
<T> - Type
A pointer type Box<T> for heap allocation.
1
rustup doc std::boxed
1
rustup doc std::option::Option
Type Option represents an optional value: every Option is either Some and contains a value, or None, and does not.
There are no "null" references. Instead, Rust has optional pointers, like the optional owned box, Option<Box<T>>.
core::convert::Infallible is the error type for errors that can never happen, hence the result is always Ok. Deprecation in favour of ! is planned.
! is a type with no values, representing the result of computations that never complete. Currently unstable.
1
2
3
fn foo() -> ! {
panic!("This call never returns.");
}
Borrow checker rules.
Trying to use data that has been passed for writing or moved results in error use of moved value.
Avoid immortal (static) references when writing asynchronous code. Allows borrowing references.
Wait for threads to complete, this happens at the end of a scope. Concurrency is a major goal of Rust, along with safety.
1
2
3
# Cargo.toml
[dependencies]
minreq = { version >= "2.14.1" }
1
2
3
4
5
6
7
8
9
// scope blocks until threads are done, therefore
// rustc has a guarantee that all threads will finish (join).
fn expensive_scope(url: &String) {
std::thread::scope(|s| {
s.spawn(|| minreq::get(url));
})
dbg!("url: {}", url);
}
Better not to use async unless threads is not enough.
tokio - most widely used async library, for network functions (need to wait for I/O). Muddies code, better to do without in the beginning. Consider a scoped tokio runtime.
std::sync::Arc - Atomically Reference Counted, thread-safe reference-counting pointer.
smol is a small and fast async runtime.
rayon - converts iterators into parallel iterators. Rayon guarantees you that using Rayon APIs will not introduce data races.
Async SQL toolkit for Rust, with compile time SQL validation.
Uses procedural macros to generate a lot of boilerplate code so your code is a clear and clean implementation of needs. Complies with the OpenAPIv3 specification.
Serialize, deserialize data types.
Backend html.
Frontend html.
Convenient, higher-level HTTP client.
Async native (tokio) logging.
Colourful, consistent, well formatted error reports.
Date and time library.
Interactive Rust read-eval-print-loop (REPL), debug, asm inspection.
1
2
:help
:quit
Tauri uses web technologies, that means that virtually any frontend framework is compatible with Tauri.
Godot has Rust bindings.