Implement fmt::Display for List in Rust

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we are implementing fmt::Display for a structure called List which contains a Vec in Rust. The challenge is to handle each element sequentially using the write! macro, as it generates a fmt::Result which needs to be properly handled. To address this, we can use the ? operator to check if write! returns an error and return it if it does, otherwise continue with the execution. By implementing fmt::Display for List, we can iterate over the elements in the vector and print them within square brackets, separated by commas. The task is to modify the program to also print the index of each element in the vector. The expected output after the modification is [0: 1, 1: 2, 2: 3].

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/DataStructuresandEnumsGroup(["`Data Structures and Enums`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/DataTypesGroup -.-> rust/integer_types("`Integer Types`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("`Method Syntax`") rust/AdvancedTopicsGroup -.-> rust/traits("`Traits`") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("`Traits for Operator Overloading`") subgraph Lab Skills rust/variable_declarations -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/integer_types -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/function_syntax -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/expressions_statements -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/method_syntax -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/traits -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} rust/operator_overloading -.-> lab-99189{{"`Implement fmt::Display for List in Rust`"}} end

Testcase: List

Implementing fmt::Display for a structure where the elements must each be handled sequentially is tricky. The problem is that each write! generates a fmt::Result. Proper handling of this requires dealing with all the results. Rust provides the ? operator for exactly this purpose.

Using ? on write! looks like this:

// Try `write!` to see if it errors. If it errors, return
// the error. Otherwise continue.
write!(f, "{}", value)?;

With ? available, implementing fmt::Display for a Vec is straightforward:

use std::fmt; // Import the `fmt` module.

// Define a structure named `List` containing a `Vec`.
struct List(Vec<i32>);

impl fmt::Display for List {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // Extract the value using tuple indexing,
        // and create a reference to `vec`.
        let vec = &self.0;

        write!(f, "[")?;

        // Iterate over `v` in `vec` while enumerating the iteration
        // count in `count`.
        for (count, v) in vec.iter().enumerate() {
            // For every element except the first, add a comma.
            // Use the ? operator to return on errors.
            if count != 0 { write!(f, ", ")?; }
            write!(f, "{}", v)?;
        }

        // Close the opened bracket and return a fmt::Result value.
        write!(f, "]")
    }
}

fn main() {
    let v = List(vec![1, 2, 3]);
    println!("{}", v);
}

Activity

Try changing the program so that the index of each element in the vector is also printed. The new output should look like this:

[0: 1, 1: 2, 2: 3]

Summary

Congratulations! You have completed the Testcase: List lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like