Hone logo
Hone
Problems

Implementing the Display Trait for Custom Types

In Rust, the std::fmt::Display trait is used to define how a type should be formatted for human-readable output, typically when using macros like println! or format!. This challenge will test your understanding of traits, generics, and how to implement custom formatting for your own data structures.

Problem Description

Your task is to implement the std::fmt::Display trait for a custom struct and an enum that you will define. This will allow instances of these types to be printed directly to the console using println! and formatted into strings using format!.

Key Requirements:

  1. Define a struct: Create a simple struct that holds a few fields (e.g., name: String, id: u32).
  2. Define an enum: Create a simple enum with a few variants, some of which might hold data.
  3. Implement Display for the struct: Implement the std::fmt::Display trait for your struct. The output should be a human-readable string representing the struct's data.
  4. Implement Display for the enum: Implement the std::fmt::Display trait for your enum. The output should clearly indicate which variant is active and display its associated data if any.
  5. Demonstrate usage: Write a main function that creates instances of your struct and enum and prints them using println!.

Expected Behavior:

When an instance of your struct is printed, it should produce a string that clearly represents its contents. For example, if a struct has name: "Alice" and id: 123, it might be displayed as "User { name: Alice, id: 123 }".

When an instance of your enum is printed, it should also clearly represent its variant and any data it holds. For example, if an enum has a variant Status(String) with the value "Active", it might be displayed as "Status: Active".

Edge Cases to Consider:

  • Empty strings for fields.
  • Enums with variants that hold no data.
  • Enums with variants that hold different types of data (e.g., a u32 vs. a String).

Examples

Example 1: Struct Display

// Assume a struct `Point` is defined as:
// struct Point {
//     x: i32,
//     y: i32,
// }
//
// And `Display` is implemented to output:
// "Point { x: 5, y: -10 }"

Input:
let p = Point { x: 5, y: -10 };
println!("{}", p);

Output:
Point { x: 5, y: -10 }

Example 2: Enum Display

// Assume an enum `ResultStatus` is defined as:
// enum ResultStatus {
//     Success(String),
//     Error(u16),
//     Pending,
// }
//
// And `Display` is implemented to output:
// For `Success("Operation complete")`: "Status: Success - Operation complete"
// For `Error(404)`: "Status: Error - Code 404"
// For `Pending`: "Status: Pending"

Input:
let res1 = ResultStatus::Success("Operation complete".to_string());
let res2 = ResultStatus::Error(404);
let res3 = ResultStatus::Pending;

println!("Result 1: {}", res1);
println!("Result 2: {}", res2);
println!("Result 3: {}", res3);

Output:
Result 1: Status: Success - Operation complete
Result 2: Status: Error - Code 404
Result 3: Status: Pending

Constraints

  • Your struct must have at least two fields.
  • Your enum must have at least three variants, with at least one variant holding data.
  • The implementation of Display should produce clear and unambiguous output.
  • You must use the std::fmt::Formatter and std::fmt::Result types within your fmt method.

Notes

  • Remember to use std::fmt; to bring the necessary traits and types into scope.
  • The fmt method signature for Display is fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result.
  • The Formatter type provides methods like write_str(), debug_tuple(), debug_struct(), etc., which are very useful for formatting. You are encouraged to explore Formatter's documentation.
  • Consider using f.debug_struct("StructName") or f.debug_tuple("EnumVariantName") for more structured output, especially for your struct and enum variants.
Loading editor...
rust