Toy project to learn Rust and Diesel.
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install Diesel CLI
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/diesel-rs/diesel/releases/latest/download/diesel_cli-installer.sh | sh
# Create database
cd develop-gears
docker compose up -d
# Database tables
diesel migration generate [migration-name]
# Run migrations
./scripts/migrate.sh
./scripts/serve-backend.sh dev
./scripts/build-migration.sh
./scripts/build-backend.sh
cd deployments
docker compose up -d
Resources:
- 🤔 https://www.reddit.com/r/rust/comments/16bswvl/looking_for_the_perfect_dockerfile_for_rust/
- https://stackoverflow.com/questions/10319652/check-if-a-file-is-executable
- https://www.shuttle.dev/blog/2024/01/09/getting-started-tracing-rust
https://stackoverflow.com/questions/49098753/unable-to-run-a-docker-image-with-a-rust-executable- https://users.rust-lang.org/t/release-binary-not-working-in-docker/36383/4
https://stackoverflow.com/questions/30780780/difference-between-stdout-and-dev-stdouthttps://stackoverflow.com/questions/74957107/how-to-conditionally-use-tracings-non-blocking-writer-instead-of-stdout
-
https://www.reddit.com/r/rust/comments/16sj6af/diesel_table_scheme_migration/
-
https://github.com/diesel-rs/diesel/blob/master/guide_drafts/trait_derives.md
-
https://stackoverflow.com/questions/77540941/rust-axum-router-sub-directories
-
https://docs.rs/axum/latest/axum/struct.Router.html#method.merge
-
https://medium.com/geekculture/dependency-injection-in-rust-3822bf689888
-
https://users.rust-lang.org/t/why-use-diesel-when-its-not-async/90160
-
https://users.rust-lang.org/t/rust-arrays-and-vectors/117607
- https://doc.rust-lang.org/cargo/guide/project-layout.html
- https://doc.rust-lang.org/cargo/reference/manifest.html
- https://github.com/janos-r/axum-template
- https://www.reddit.com/r/learnrust/comments/13gbrf4/to_move_or_to_borrow/
- https://users.rust-lang.org/t/rationale-for-move-copy-borrow-syntax/87493
Why This Design? Rust’s Ownership Model
let mut b1 = 1;
let b2 = &mut b1;
let b3 = &mut b1; // Fail. Cannot mutably borrow when already mutably borrowed
println!("{:?} {:?} {:?}", b1, b2, b3);
- First Mutable Borrow: The line
let b2 = &mut b1;
creates a mutable reference tob1
. At this point,b1
is mutably borrowed byb2
. - Second Mutable Borrow: The line
let b3 = &mut b1;
attempts to create another mutable reference tob1
. This violates Rust’s borrowing rules becauseb1
is already mutably borrowed byb2
. Rust does not allow multiple mutable borrows at the same time to prevent data races. - Borrow Checker Error: The compiler throws an error because it detects that
b1
is being borrowed mutably more than once at the same time, which could lead to undefined behavior if allowed.
Rust’s design aims to prevent data races at compile time by enforcing these borrowing rules. Data races occur when two or more threads access shared data simultaneously, and at least one of the accesses is a write. By ensuring that only one mutable reference exists at any given time, Rust guarantees that no other part of the program can modify the data unexpectedly, thus maintaining memory safety and preventing data races. This approach allows Rust to provide high performance and safety guarantees without needing a garbage collector, making it suitable for systems programming where both efficiency and reliability are critical.
To illustrate the necessity of using macros in Rust, let's consider a situation where you need to generate repetitive or boilerplate code. Macros provide a powerful way to automate this process, reducing errors and improving maintainability.
Lifetimes are a fundamental concept in Rust that help the compiler ensure memory safety without the need for a garbage collector. Understanding lifetimes is crucial for writing safe and efficient Rust code.
You should use core::result::Result
when you need to represent the outcome of an operation that can either succeed or fail. This type is particularly useful in functions that may encounter errors and need to propagate them to the caller.