Skip to content

Workflow: Beginner Path ​

Updated Mar 2026

Overview ​

A structured learning roadmap from zero Rust knowledge to building real applications. Follow this path in order.

Learning Roadmap ​

Phase 1: Setup and Basics (Week 1-2) ​

Install Rust ​

bash
# Install rustup (manages Rust versions)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Verify installation
rustc --version
cargo --version

# Install essential tools
rustup component add clippy rustfmt

Hello World ​

rust
fn main() {
    println!("Hello, Rust!");
}
bash
cargo new hello_rust
cd hello_rust
cargo run

Variables, Types, Functions ​

rust
fn main() {
    // Immutable by default
    let x = 5;
    let mut y = 10;  // Mutable
    y += x;

    // Type annotation
    let z: f64 = 3.14;

    // Shadowing (re-declare)
    let spaces = "   ";
    let spaces = spaces.len();  // Different type!

    println!("{y}, {z}, {spaces}");
}

// Functions with types
fn add(a: i32, b: i32) -> i32 {
    a + b  // No semicolon = expression (returned)
}

// Control flow
fn classify(n: i32) -> &'static str {
    if n < 0 {
        "negative"
    } else if n == 0 {
        "zero"
    } else {
        "positive"
    }
}

Key Exercises ​

  1. Write a temperature converter (Fahrenheit to Celsius)
  2. Generate the nth Fibonacci number
  3. Print lyrics to "The Twelve Days of Christmas"

Phase 2: Ownership (Week 3-4) ​

This is the most important concept in Rust. Spend extra time here.

Must-Know Concepts ​

rust
fn main() {
    // MOVE: String is heap-allocated
    let s1 = String::from("hello");
    let s2 = s1;  // s1 is invalid now
    // println!("{s1}");  // Compile error!

    // COPY: i32 is stack-only
    let n1 = 42;
    let n2 = n1;  // Both valid
    println!("{n1} {n2}");

    // BORROW: use without taking ownership
    let s3 = String::from("world");
    let len = calculate_length(&s3);  // Borrow
    println!("{s3} has length {len}"); // Still valid!

    // SLICE: reference to a portion
    let s4 = String::from("hello world");
    let hello = &s4[0..5];  // &str slice
    println!("{hello}");
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Phase 3: Data Modeling (Week 5-6) ​

rust
// Structs for structured data
struct User {
    name: String,
    email: String,
    active: bool,
}

impl User {
    fn new(name: String, email: String) -> Self {
        User { name, email, active: true }
    }

    fn deactivate(&mut self) {
        self.active = false;
    }
}

// Enums for variants
enum Shape {
    Circle(f64),               // radius
    Rectangle(f64, f64),       // width, height
    Triangle { base: f64, height: f64 },
}

impl Shape {
    fn area(&self) -> f64 {
        match self {
            Shape::Circle(r) => std::f64::consts::PI * r * r,
            Shape::Rectangle(w, h) => w * h,
            Shape::Triangle { base, height } => 0.5 * base * height,
        }
    }
}

fn main() {
    let shapes: Vec<Shape> = vec![
        Shape::Circle(5.0),
        Shape::Rectangle(4.0, 6.0),
        Shape::Triangle { base: 3.0, height: 8.0 },
    ];

    for shape in &shapes {
        println!("Area: {:.2}", shape.area());
    }
}

Phase 4: Error Handling + Traits (Week 7-8) ​

rust
use std::fmt;
use std::fs;

// Custom error
#[derive(Debug)]
enum AppError {
    IoError(std::io::Error),
    ParseError(String),
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AppError::IoError(e) => write!(f, "IO error: {e}"),
            AppError::ParseError(msg) => write!(f, "Parse error: {msg}"),
        }
    }
}

impl From<std::io::Error> for AppError {
    fn from(e: std::io::Error) -> Self {
        AppError::IoError(e)
    }
}

// Trait for shared behavior
trait Describable {
    fn describe(&self) -> String;
}

impl Describable for User {
    fn describe(&self) -> String {
        format!("{} ({})", self.name, self.email)
    }
}

Phase 5: Collections + Iterators (Week 9-10) ​

rust
use std::collections::HashMap;

fn main() {
    // Vec
    let mut scores = vec![85, 92, 78, 95, 88];
    scores.sort();
    let average: f64 = scores.iter().sum::<i32>() as f64 / scores.len() as f64;

    // HashMap
    let mut word_count: HashMap<String, u32> = HashMap::new();
    let text = "hello world hello rust hello";
    for word in text.split_whitespace() {
        *word_count.entry(word.to_string()).or_insert(0) += 1;
    }

    // Iterator chains
    let top_words: Vec<_> = word_count
        .iter()
        .filter(|(_, &count)| count > 1)
        .map(|(word, count)| format!("{word}: {count}"))
        .collect();

    println!("Average: {average:.1}");
    println!("Top words: {top_words:?}");
}

Phase 6: First Project (Week 11-12) ​

Pick one and build it:

ProjectSkills Used
CLI todo appStructs, enums, file I/O, serde, clap
Grep cloneFile I/O, iterators, pattern matching, CLI args
URL shortener APIAxum/Actix, HashMap, async, HTTP
Markdown to HTML converterString processing, enums, parsing

Starter: CLI Todo App ​

rust
use serde::{Serialize, Deserialize};
use std::fs;

#[derive(Serialize, Deserialize, Debug)]
struct Todo {
    id: u32,
    title: String,
    done: bool,
}

#[derive(Serialize, Deserialize, Debug, Default)]
struct TodoList {
    todos: Vec<Todo>,
    next_id: u32,
}

impl TodoList {
    fn add(&mut self, title: String) {
        self.next_id += 1;
        self.todos.push(Todo {
            id: self.next_id,
            title,
            done: false,
        });
    }

    fn complete(&mut self, id: u32) -> bool {
        if let Some(todo) = self.todos.iter_mut().find(|t| t.id == id) {
            todo.done = true;
            true
        } else {
            false
        }
    }

    fn save(&self, path: &str) -> Result<(), Box<dyn std::error::Error>> {
        let json = serde_json::to_string_pretty(self)?;
        fs::write(path, json)?;
        Ok(())
    }

    fn load(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let data = fs::read_to_string(path)?;
        let list: TodoList = serde_json::from_str(&data)?;
        Ok(list)
    }
}

Resources ​

ResourceTypeURL
The Rust BookOfficial guidedoc.rust-lang.org/book
Rust by ExampleInteractive examplesdoc.rust-lang.org/rust-by-example
RustlingsExercisesgithub.com/rust-lang/rustlings
Exercism Rust TrackPractice problemsexercism.org/tracks/rust
Rust PlaygroundOnline compilerplay.rust-lang.org

Built with VitePress | Rust SOP Documentation