Introduction to Rust

Rust Essentials

Introduction to Rust

Building a Task Manager in Rust

Building a Task Manager in Rust

This milestone project will provide an excellent opportunity to consolidate your learning and showcase your mastery of Rust programming. It combines concepts from each guide into a real-world application, allowing you to see how they interact and complement each other in a practical setting.

Happy coding!

Step 1: Initialize the project

Run:

cargo new task_manager

When this is created, open the project in your code editor.

Step 2: Create a module named task

Inside of the src/ directory, create a directory named task, then create a mod.rs file and a task.rs file:

.
├── Cargo.toml
└── src/
   ├── main.rs
   └── task/
      ├── mod.rs
      └── task.rs

Step 3: Add the chrono crate for working with time

Run:

cargo add chrono

When it is done installing the crate, check that chrono and its version are recorded in the [dependencies] section of the Cargo.toml file.

Step 4: Create the Task struct

Create the Task struct inside of task.rs to handle task descriptions.

pub struct Task {
    pub title: String,
    pub description: String,
    pub due_date: chrono::NaiveDate,
    pub completed: bool,
}

impl Task {
    pub fn new(title: String, description: String, due_date: chrono::NaiveDate) -> Self {
        Task {
            title,
            description,
            due_date,
            completed: false,
        }
    }
}

Note: You can one of the ways an imported crate is used. But we will also have to call it properly in the main.rs file, as you will soon see. Also, we are yet to explore advanced method implementations, but this is what it looks like. Remember to export the task.rs file inside mod.rs:

pub mod task;

Step 5: Create the main program

Use the task module inside the main program:

pub mod task;
pub use task::task::Task;

use std::io;
use chrono::prelude::Local;

fn main() {
    println!("Welcome to Rusty Task Manager!\\n");

    let tasks: Vec<Task> = Vec::new();

    loop {
        println!("Commands:");
        println!("- add <title> <description> <due_date>");
        println!("- view");
        println!("- complete <task_index>");
        println!("- filter <completed | upcoming>\\n");

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

        let parts: Vec<&str> = input.trim().split_whitespace().collect();
        match parts[0] {
            // ... rest of the code remains the same
            "filter" => {
                if parts.len() == 2 {
                    match parts[1] {
                        "completed" => {
                            for (index, task) in tasks.iter().enumerate().filter(|t| t.1.completed) {
                                println!("{}. {} [Complete]", index + 1, task.title);
                            }
                        }
                        "upcoming" => {
                            let today = Local::today().naive_local();
                            for (index, task) in tasks.iter().enumerate().filter(|t| t.1.due_date >= today) {
                                let status = if task.completed { "[Complete]" } else { "[Incomplete]" };
                                println!("{}. {} {} (Due: {})", index + 1, task.title, status, task.due_date);
                            }
                        }
                        _ => println!("Invalid filter option."),
                    }
                } else {
                    println!("Invalid input. Use: filter <completed | upcoming>");
                }
            }
            _ => println!("Invalid command."),
        }
    }
}

Step 6: Run the project

Run:

cargo run

The project should run as expected. There you go! You have built your first real-world application in Rust.

Note: You can run cargo build instead to make Cargo build a binary file for the project with the same name as the project name. Then you can change the directory into target/debug/, where there is a task_manager binary executable that you can run like this:

./task_manager

Untitled (22).png

You can tweak this project to find ways to improve it. Otherwise, see you in the Intermediate Rust series!

Whenever you're ready

There are 4 ways we can help you become a great backend engineer:

The MB Platform

Join 1000+ backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.

The MB Academy

The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.

Join Backend Weekly

If you like post like this, you will absolutely enjoy our exclusive weekly newsletter, Sharing exclusive backend engineering resources to help you become a great Backend Engineer.

Get Backend Jobs

Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board