C.W.K.
Stream
Lesson 01 of 07 · published

Rust Survival Kit for Web Devs

~16 min · rust, ownership, result, survival

Level 0Web Tourist
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"You don't need to win a fight with the borrow checker. You need to ship a command. Those are very different goals."

The Five Ideas That Get You Productive

You can write useful Tauri commands knowing a small slice of Rust. Here's the slice:

  • Ownership & borrowing. Every value has exactly one owner. Pass it and you move it (the old name can't use it anymore), or lend it with a reference: &T to read, &mut T to modify. The compiler enforces this so you can't have a use-after-free or a data race. For most commands you take owned arguments and return owned values — the simplest case.
  • No null — Option<T>. A value that might be absent is Some(x) or None. The compiler forces you to handle the None case, which is why Rust programs don't get null-pointer surprises.
  • No exceptions — Result<T, E>. A fallible operation returns Ok(value) or Err(error). This is the type your commands return, and it maps straight onto resolved/rejected Promises.
  • Structs + derive. A struct is your data shape; #[derive(Serialize, Deserialize)] auto-generates the code to send it across the bridge.
  • String vs &str. String is an owned, growable string; &str is a borrowed view. Take String as a command argument and you don't have to think about lifetimes.

The Compiler Is a Strict Tutor, Not an Enemy

Rust's error messages are unusually good — they often tell you the exact fix. When the borrow checker complains, it's catching a real bug class (a dangling reference, a race) before it can exist. Treat red squiggles as a free senior reviewer. The ? operator is your friend here too: it unwraps an Ok or early-returns the Err, turning verbose error handling into one character.

And When You Want More

This is survival, not mastery — deliberately. Traits, lifetimes, generics, iterators, async internals: that's a whole language worth learning, and it gets its own quest at /cwk-quests/rust-quest. You don't need any of it to wire your first ten commands. Build first; deepen later.

Code

The whole survival kit in one screen·rust
use serde::{Serialize, Deserialize};

// A data shape that can cross the bridge (note the derives).
#[derive(Serialize, Deserialize)]
struct Note {
    id: u32,
    title: String,   // owned string — no lifetime headaches
    body: String,
}

// Option<T>: a value that might not be there.
fn find_title(notes: &[Note], id: u32) -> Option<String> {
    for n in notes {
        if n.id == id {
            return Some(n.title.clone());
        }
    }
    None
}

// Result<T, E>: an operation that can fail. `?` propagates the error.
fn parse_count(raw: &str) -> Result<u32, std::num::ParseIntError> {
    let n: u32 = raw.trim().parse()?; // ? returns early on Err
    Ok(n * 2)
}

External links

Exercise

Write three tiny Rust functions (in a scratch file or the Rust Playground): one returning Option<String>, one returning Result<u32, String>, and one taking a struct you defined with #[derive(Serialize)]. Make them compile. You're not building Tauri yet — you're proving the survival kit is enough to express real logic.
Hint
Use play.rust-lang.org if you don't want to set up a project. For the Result one, return Err("some message".to_string()) on the failure path so the error type is String — the exact shape your Tauri commands will use.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.