Link to this headingRust

OffensiveRust
200ThingsToRememberAboutRust
Embedded in Rust
Making a C++ Lib with Rust
Creating a statically linked Rust application
Automatically generates Rust FFI bindings to C (and some C++) libraries.
Rust GUI
Cross-platform Rust GUI
https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials
https://fasterthanli.me/articles/a-half-hour-to-learn-rust
https://github.com/Dhghomon/easy_rust

Faster Compile times

Good libraries:

Link to this headingRust Web

mixedbread
axum
maud
htmx
hx-preload

Link to this headingRust Memory

What Each memory option is for a rust variable

Link to this headingCargo Settings

Make debug builds smaller:

export CARGO_PROFILE_RELEASE_LTO=thin

Change the Linker to another executable on linux:

[target.x86_64-unknown-linux-gnu] rustflags = [ "-C", "link-arg=-fuse-ld=lld", ]

Overwrite Linker options:

rustflags=( "-C link-arg=-fuse-ld=lld" "-C link-arg=-Wl,--compress-debug-sections=zlib" "-C force-frame-pointers=yes" ) export RUSTFLAGS="${rustflags[*]}"

Link to this headingExample Cargo.toml

[package] name = "ping" version = "0.1.0" edition = "2021" [dependencies] #delf = { path = "../delf" } #Used to specify a library in another directory [profile.release] strip = true # Automatically strip symbols from the binary. #opt-level = "z" # Optimize for size. opt-level = "s" # Optimize for size. lto = true # Used to remove deadcode and unused functions panic = "abort" # Remove backtrace when crashes

Link to this headingBuilding

Build and Run the release version with command line arguments:

>>> cargo run --release -- arg1 arg2

Install other versions of rust:

>>> rustup toolchain install nightly-2022-11-06

Run other version of rust:

>>> rustup run nightly cargo build >>> cargo +nightly-2022-11-06 build --release

Cross Compiling:

>>> rustup run nightly rustc --print target-list aarch64-apple-darwin aarch64-apple-ios aarch64-apple-ios-macabi aarch64-apple-ios-sim aarch64-apple-tvos aarch64-apple-watchos-sim aarch64-fuchsia aarch64-kmc-solid_asp3 aarch64-linux-android aarch64-nintendo-switch-freestanding aarch64-pc-windows-gnullvm aarch64-pc-windows-msvc aarch64-unknown-freebsd aarch64-unknown-hermit aarch64-unknown-linux-gnu aarch64-unknown-linux-gnu_ilp32 aarch64-unknown-linux-musl aarch64-unknown-netbsd aarch64-unknown-none aarch64-unknown-none-softfloat aarch64-unknown-nto-qnx710 aarch64-unknown-openbsd aarch64-unknown-redox aarch64-unknown-uefi aarch64-uwp-windows-msvc aarch64-wrs-vxworks aarch64_be-unknown-linux-gnu aarch64_be-unknown-linux-gnu_ilp32 arm-linux-androideabi arm-unknown-linux-gnueabi arm-unknown-linux-gnueabihf arm-unknown-linux-musleabi arm-unknown-linux-musleabihf arm64_32-apple-watchos armeb-unknown-linux-gnueabi armebv7r-none-eabi armebv7r-none-eabihf armv4t-none-eabi armv4t-unknown-linux-gnueabi armv5te-none-eabi armv5te-unknown-linux-gnueabi armv5te-unknown-linux-musleabi armv5te-unknown-linux-uclibceabi armv6-unknown-freebsd armv6-unknown-netbsd-eabihf armv6k-nintendo-3ds armv7-apple-ios armv7-linux-androideabi armv7-unknown-freebsd armv7-unknown-linux-gnueabi armv7-unknown-linux-gnueabihf armv7-unknown-linux-musleabi armv7-unknown-linux-musleabihf armv7-unknown-linux-uclibceabi armv7-unknown-linux-uclibceabihf armv7-unknown-netbsd-eabihf armv7-wrs-vxworks-eabihf armv7a-kmc-solid_asp3-eabi armv7a-kmc-solid_asp3-eabihf armv7a-none-eabi armv7a-none-eabihf armv7k-apple-watchos armv7r-none-eabi armv7r-none-eabihf armv7s-apple-ios asmjs-unknown-emscripten avr-unknown-gnu-atmega328 bpfeb-unknown-none bpfel-unknown-none hexagon-unknown-linux-musl i386-apple-ios i586-pc-windows-msvc i586-unknown-linux-gnu i586-unknown-linux-musl i686-apple-darwin i686-linux-android i686-pc-windows-gnu i686-pc-windows-msvc i686-unknown-freebsd i686-unknown-haiku i686-unknown-linux-gnu i686-unknown-linux-musl i686-unknown-netbsd i686-unknown-openbsd i686-unknown-uefi i686-uwp-windows-gnu i686-uwp-windows-msvc i686-wrs-vxworks m68k-unknown-linux-gnu mips-unknown-linux-gnu mips-unknown-linux-musl mips-unknown-linux-uclibc mips64-openwrt-linux-musl mips64-unknown-linux-gnuabi64 mips64-unknown-linux-muslabi64 mips64el-unknown-linux-gnuabi64 mips64el-unknown-linux-muslabi64 mipsel-sony-psp mipsel-sony-psx mipsel-unknown-linux-gnu mipsel-unknown-linux-musl mipsel-unknown-linux-uclibc mipsel-unknown-none mipsisa32r6-unknown-linux-gnu mipsisa32r6el-unknown-linux-gnu mipsisa64r6-unknown-linux-gnuabi64 mipsisa64r6el-unknown-linux-gnuabi64 msp430-none-elf nvptx64-nvidia-cuda powerpc-unknown-freebsd powerpc-unknown-linux-gnu powerpc-unknown-linux-gnuspe powerpc-unknown-linux-musl powerpc-unknown-netbsd powerpc-unknown-openbsd powerpc-wrs-vxworks powerpc-wrs-vxworks-spe powerpc64-ibm-aix powerpc64-unknown-freebsd powerpc64-unknown-linux-gnu powerpc64-unknown-linux-musl powerpc64-unknown-openbsd powerpc64-wrs-vxworks powerpc64le-unknown-freebsd powerpc64le-unknown-linux-gnu powerpc64le-unknown-linux-musl riscv32gc-unknown-linux-gnu riscv32gc-unknown-linux-musl riscv32i-unknown-none-elf riscv32im-unknown-none-elf riscv32imac-unknown-none-elf riscv32imac-unknown-xous-elf riscv32imc-esp-espidf riscv32imc-unknown-none-elf riscv64gc-unknown-freebsd riscv64gc-unknown-linux-gnu riscv64gc-unknown-linux-musl riscv64gc-unknown-none-elf riscv64gc-unknown-openbsd riscv64imac-unknown-none-elf s390x-unknown-linux-gnu s390x-unknown-linux-musl sparc-unknown-linux-gnu sparc64-unknown-linux-gnu sparc64-unknown-netbsd sparc64-unknown-openbsd sparcv9-sun-solaris thumbv4t-none-eabi thumbv5te-none-eabi thumbv6m-none-eabi thumbv7a-pc-windows-msvc thumbv7a-uwp-windows-msvc thumbv7em-none-eabi thumbv7em-none-eabihf thumbv7m-none-eabi thumbv7neon-linux-androideabi thumbv7neon-unknown-linux-gnueabihf thumbv7neon-unknown-linux-musleabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf wasm32-unknown-emscripten wasm32-unknown-unknown wasm32-wasi wasm64-unknown-unknown x86_64-apple-darwin x86_64-apple-ios x86_64-apple-ios-macabi x86_64-apple-tvos x86_64-apple-watchos-sim x86_64-fortanix-unknown-sgx x86_64-fuchsia x86_64-linux-android x86_64-pc-nto-qnx710 x86_64-pc-solaris x86_64-pc-windows-gnu x86_64-pc-windows-gnullvm x86_64-pc-windows-msvc x86_64-sun-solaris x86_64-unknown-dragonfly x86_64-unknown-freebsd x86_64-unknown-haiku x86_64-unknown-hermit x86_64-unknown-illumos x86_64-unknown-l4re-uclibc x86_64-unknown-linux-gnu x86_64-unknown-linux-gnux32 x86_64-unknown-linux-musl x86_64-unknown-netbsd x86_64-unknown-none x86_64-unknown-openbsd x86_64-unknown-redox x86_64-unknown-uefi x86_64-uwp-windows-gnu x86_64-uwp-windows-msvc x86_64-wrs-vxworks >>> rustup run nightly rustup toolchain install nightly-2022-11-06-i686-pc-windows-msvc >>> rustup run nightly rustup target add i686-pc-windows-msvc >>> rustup run nightly cargo build --target i686-pc-windows-msvc

Link to this headingExpanding Macros

cargo expand

Link to this headingLearning Rust

https://rustforjs.dev/
How I went about learning Rust
Roguelike Tutorial - In Rust
Writing an OS in Rust

Link to this headingExamples

https://medium.com/@ilegra/building-a-microservice-with-rust-ef9641cf2331

Link to this headingConcepts

https://doc.rust-lang.org/std/clone/trait.Clone.html
https://depth-first.com/articles/2020/01/27/rust-ownership-by-example/
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
https://doc.rust-lang.org/rust-by-example/scope/lifetime.html

Smart Pointers:

  • Box<T>: To store something on the heap.
    • Used when you don’t know the size at compile time.
    • Used when the type is recursive
  • Rc<T>: If you need to have multiple functions referencing the underlined data structure
    • Is only de allocated when all references are removed from scope
  • Arc<T>: Atomic Reference Counters
    • Used when need multiple threads interacting with the same object

Async:
(async) Rust doesn’t have to be hard

Link to this headingMacros

Simple Macro for a Function:

macro_rules! create_function { // This macro takes an argument of designator `ident` and // creates a function named `$func_name`. // The `ident` designator is used for variable/function names. ($func_name:ident) => { fn $func_name() { // The `stringify!` macro converts an `ident` into a string. println!("You called {:?}()", stringify!($func_name)); } }; } // Create functions named `foo` and `bar` with the above macro. create_function!(foo); create_function!(bar); fn main() { foo(); bar(); }

Macro for many arguments:

// `find_min!` will calculate the minimum of any number of arguments. macro_rules! find_min { // Base case: ($x:expr) => ($x); // `$x` followed by at least one `$y,` ($x:expr, $($y:expr),+) => ( // Call `find_min!` on the tail `$y` std::cmp::min($x, find_min!($($y),+)) ) } fn main() { println!("{}", find_min!(1)); println!("{}", find_min!(1 + 2, 2)); println!("{}", find_min!(5, 2 * 3, 4)); }

Link to this headingBorrowing

Immutable Borrow:

fn main() { let mut s = String::from("hello world goodbye universe"); // You can make as many imputable borrow that you want let r1 = &s[0..5]; let r2 = &s[6..11]; let r3 = &s[12..19]; let r4 = &s[20..28]; println!("{}, {}, and {} {}", r1, r2, r3, r4); //Only after r1, r2, and r3 are not used anymore in the scope can you use a mutable reference let r5 = &mut s; // no problem println!("{}", r5); } fn change(some_string: &mut String) { some_string.push_str(", world"); } fn calculate_length(s: &String) -> usize { s.len() }

Mutable Borrowing:

fn main() { let mut s = String::from("hello"); //Make a mutable string // If this is in a scope then it will be removed at the end of the let r1 = &mut s; // Since you have a mutable borrow then you cant have a immutable borrow. The following will fail // let r2 = &mut s; change(r1); // Since there is a mutable variables based on s you cant use s only r1 until it is removed println!("{}", r1); } fn change(some_string: &mut String) { some_string.push_str(", world"); } fn calculate_length(s: &String) -> usize { s.len() }

No Dangling Return:

fn main() { let reference_to_nothing = no_dangle(); println!("{}", reference_to_nothing); } fn no_dangle() -> String { let s = String::from("hello"); //You cant return a reference to a string that was created in this function scope //&s s }

String Slice Borrowing:

let s = String::from("hello world"); let hello = &s[0..5]; let world = &s[6..11]; println!("{}", reference_to_nothing);

Link to this headingImporting from other files

Source

In the main.rs file you need include mod filename;. This links the file to main function. Then in the actual file you can import the module with use crate::filename;

Link to this headingOperators

?: if the function returns a Result or Option this extracts the value or the error from the result

Link to this headingLoops

Breaking Named:

#![allow(unreachable_code)] fn main() { 'outer: loop { println!("Entered the outer loop"); 'inner: loop { println!("Entered the inner loop"); // This would break only the inner loop //break; // This breaks the outer loop break 'outer; } println!("This point will never be reached"); } println!("Exited the outer loop"); }

Loop over Mutable:

fn main() { let mut names = vec!["Bob", "Frank", "Ferris"]; for name in names.iter_mut() { *name = match name { &mut "Ferris" => "There is a rustacean among us!", _ => "Hello", } } println!("names: {:?}", names); }

Link to this headingStructures

Remove Padding in structures:

fn main() { struct Foo { a: u8, b: u32, } #[repr(packed)] struct FooPacked { a: u8, b: u32, } use std::mem::size_of; println!("Foo = {}", size_of::<Foo>()); println!("FooPacked = {}", size_of::<FooPacked>()); }

Remove Reorder:

fn main() { // first, let's declare both structs: with Rust repr struct IOI_Rust { ttl: u8, tos: u8, flags: u8, options_size: u8, options_data: u32, } // and C repr #[repr(C)] struct IOI_C { ttl: u8, tos: u8, flags: u8, options_size: u8, options_data: u32, } use memoffset::span_of; use std::mem::size_of; // let's make a quick macro, this will make this a lot easier macro_rules! print_offset { // the macro takes one identifier (the struct's name), then a tuple // of identifiers (the field names) ($type: ident, ($($field: ident),*)) => { // `$type` is an identifier, but we're going to // print it out, so we need it as a string instead. let t = stringify!($type); // this will repeat for each $field $( let f = stringify!($field); let span = span_of!($type, $field); println!("{:10} {:15} {:?}", t, f, span); )* // finally, print the total field size let ts = size_of::<$type>(); println!("{:10} {:15} {}", t, "(total)", ts); println!(); }; } print_offset!(IOI_Rust, (ttl, tos, flags, options_size, options_data)); print_offset!(IOI_C, (ttl, tos, flags, options_size, options_data)); } /* IOI_Rust ttl 4..5 IOI_Rust tos 5..6 IOI_Rust flags 6..7 IOI_Rust options_size 7..8 IOI_Rust options_data 0..4 IOI_Rust (total) 8 IOI_C ttl 0..1 IOI_C tos 1..2 IOI_C flags 2..3 IOI_C options_size 3..4 IOI_C options_data 4..8 IOI_C (total) 8 */

Link to this headingLifetimes

#[derive(Debug)] struct Point(i32, i32); //Used to keep the lifetime of the function to the parent function fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point { if p1.0 < p2.0 { p1 } else { p2 } } fn main() { let p1: Point = Point(10, 10); let p2: Point = Point(20, 20); let p3 = left_most(&p1, &p2); // What is the lifetime of p3? println!("p3: {p3:?}"); }

Link to this headingEmbedded

https://esp32.implrust.com/rfid/rc522.html
https://github.com/embassy-rs/embassy

Link to this headingHacking

Linux Kernel Crate

Link to this headingHooking Golang

https://github.com/metalbear-co/mirrord/blob/main/mirrord/layer/src/hooks.rs

Link to this headingHypervisor

https://memn0ps.github.io/hypervisor-development-in-rust-part-1/?ref=upstract.com