Your First Rust App: A Step-by-Step Guide

Your First Rust App: A Step-by-Step Guide

Welcome to the world of Rust! This is an opinionated, hands-on guide designed for complete beginners. Forget the theory for a moment—we’re going to get you from zero to a small, functional command-line app and introduce you to key concepts along the way.

Ready? Let’s dive in.

1. Install Rust

The best way to install Rust is with rustup, the official toolchain manager. It’s the simplest and most reliable method for keeping your installation up-to-date.

  • macOS / Linux: Open your terminal and run the following commands:Bashcurl https://sh.rustup.rs -sSf | sh source $HOME/.cargo/env
  • Windows: Download and run rustup-init.exe from the official Rust website. Accept the default installation options.

After the installation is complete, open a new terminal (or Command Prompt/PowerShell on Windows) and verify everything is working by running:

Bash

rustc --version
cargo --version

You should see version numbers for both rustc (the Rust compiler) and Cargo (Rust’s build tool and package manager).


2. Create and Run Your First Project

Cargo is a cornerstone of the Rust ecosystem. It handles everything from creating new projects to building, testing, and managing dependencies. Let’s use it to get started.

Bash

cargo new hello-rust
cd hello-rust

This command scaffolds a new binary application called hello-rust. You now have a clean project structure:

hello-rust/
├─ Cargo.toml       # Project metadata & dependencies
└─ src/
   └─ main.rs       # The entry point for your application

To run the default “Hello, world!” program, use the cargo run command.

Bash

cargo run

The first run will take a moment as Cargo compiles your code and its dependencies. On subsequent runs, it will be lightning fast. You should see:

Hello, world!

3. Make It Interactive

Now let’s replace the default program with something more useful. Open src/main.rs in your favorite code editor and replace its contents with the following code.

Rust

use std::io::{self, Write};

fn main() {
    print!("What is your name? ");
    io::stdout().flush().unwrap();

    let mut name = String::new();
    io::stdin().read_line(&mut name).expect("Failed to read input");
    let name = name.trim();

    println!("Hi, {name}! Welcome to Rust 🚀");
}

This code does a few things:

  • use std::io... brings the standard I/O library into scope.
  • let mut name... declares a mutable variable. In Rust, variables are immutable by default, which is a powerful safety feature.
  • io::stdin().read_line... reads a line from the user’s input.
  • println! is a macro (note the !) that prints formatted text to the console.

Run the new program with cargo run and see what happens!


4. Add Real Logic: A Temperature Converter

Reading a user’s name is cool, but let’s do something more complex. Replace the code in src/main.rs with this simple temperature converter that converts Celsius to Fahrenheit.

Rust

use std::io::{self, Write};

fn main() {
    print!("Enter temperature in °C: ");
    io::stdout().flush().unwrap();

    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("read failed");

    let celsius: f64 = match input.trim().parse() {
        Ok(v) => v,
        Err(_) => {
            eprintln!("Please enter a valid number, e.g., 36.6");
            return;
        }
    };

    let fahrenheit = c_to_f(celsius);
    println!("{celsius}°C is {fahrenheit}°F");
}

fn c_to_f(c: f64) -> f64 {
    (c * 9.0 / 5.0) + 32.0
}

This example introduces some key Rust concepts:

  • match is a powerful construct for handling different outcomes, similar to a switch statement but more expressive.
  • The parse() method on a string returns a Result type, which can be either an Ok(value) or an Err(error). This is Rust’s preferred way of handling fallible operations instead of throwing exceptions.
  • fn c_to_f(...) -> f64 defines a function that takes a floating-point number (f64) as input and returns one.

Now run cargo run and test it out!


5. Add a Dependency and Write a Test

The Rust ecosystem is built on crates (libraries) published to crates.io. To use a crate, you simply add it to your Cargo.toml file.

Open Cargo.toml and add the rand crate under the [dependencies] section.

Ini, TOML

[dependencies]
rand = "0.8"

Now, replace the code in src/main.rs with this simple number-guessing game.

Rust

use rand::Rng;

fn main() {
    let secret = rand::thread_rng().gen_range(1..=10);
    println!("I picked a number between 1 and 10: {secret}");
}

When you run cargo run, Cargo will automatically download and compile the rand crate for you.

Write a Test

A core part of building reliable software is writing tests. Let’s add a unit test for our temperature conversion function (from step 4) to ensure it works correctly.

Add the following block of code to the bottom of your src/main.rs file.

Rust

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn converts_correctly() {
        assert_eq!(c_to_f(0.0), 32.0);
    }
}
  • #[cfg(test)] tells Rust to only compile this code when running tests.
  • mod tests creates a new module for our tests.
  • #[test] marks the converts_correctly function as a test.
  • assert_eq! is a macro that panics if the two arguments are not equal.

Run your new test with cargo test and watch it pass.


6. Build and Ship Your App

When you run cargo build, it creates a debug version of your executable in target/debug/hello-rust. For a production-ready application, you want to build an optimized, fast binary.

Bash

cargo build --release

This generates an optimized executable and places it in target/release/hello-rust. This is the file you would distribute to others.


What’s Next?

Congratulations! You just installed Rust, built and ran a project, handled user input, added logic and a dependency, wrote a test, and built a release binary. That’s a solid first lap.

Here are a few things to explore next:

  • Code Organization: Learn how to split your code into modules and different files.
  • Error Handling: Dig deeper into Rust’s Result and Option types and how to handle errors gracefully.
  • Advanced Concepts: Explore structs, enums, slices, and the core concepts of ownership and borrowing.

Ready for your next challenge? Try a tiny REST client or a simple game when you feel ready.

Do you have a specific goal you’d like to achieve with Rust?

felixrante.com - First Rust App

Leave a Reply

Your email address will not be published. Required fields are marked *


Translate »