Hone logo
Hone
Problems

Implementing Generic Data Structures with Trait Specialization in Rust

This challenge focuses on understanding and implementing a core concept in Rust's generics: trait specialization. You will build a simple data structure that can behave differently based on the type of data it holds, demonstrating how to specialize trait implementations for specific types. This is crucial for optimizing performance and providing type-specific behavior in generic code.

Problem Description

Your task is to create a generic Container struct in Rust. This Container should be able to store a single value of any type T. You will then define a trait, let's call it DisplayInfo, which has a method display_details().

The display_details() method should provide a generic output for most types. However, you need to specialize the implementation of DisplayInfo for String and i32 types to provide more specific and informative output.

Requirements:

  1. Generic Container<T> struct: This struct should hold a single value of type T.
  2. DisplayInfo trait:
    • Define a trait DisplayInfo with a method fn display_details(&self);.
    • This method should take &self and print information to the console.
  3. Generic DisplayInfo implementation: Provide a default implementation of DisplayInfo for any type T that implements the std::fmt::Debug trait. This implementation should print a message like "Generic container holds: [debug representation]".
  4. Specialized DisplayInfo for String: Implement DisplayInfo specifically for Container<String>. This implementation should print a message like "String container holds: [string value] (Length: [string length])".
  5. Specialized DisplayInfo for i32: Implement DisplayInfo specifically for Container<i32>. This implementation should print a message like "Integer container holds: [integer value] (Is even: [true/false])".
  6. Demonstrate usage: Create instances of Container with different types (String, i32, and another generic type like f64) and call their display_details() methods to show the specialized and generic behaviors.

Expected Behavior:

  • When display_details() is called on a Container<String>, the specialized String output should be printed.
  • When display_details() is called on a Container<i32>, the specialized i32 output should be printed.
  • When display_details() is called on a Container of any other type (e.g., f64) that implements Debug, the generic output should be printed.

Edge Cases:

  • Ensure the Container can handle various types, including primitive types and user-defined types (as long as they implement Debug for the generic case).

Examples

Example 1:

Input:
let string_container = Container { value: String::from("Hello, Rust!") };
string_container.display_details();
Output:
String container holds: Hello, Rust! (Length: 12)

Explanation: The input is a Container holding a String. The specialized String implementation of display_details is called, printing the string value and its length.

Example 2:

Input:
let int_container = Container { value: 42 };
int_container.display_details();
Output:
Integer container holds: 42 (Is even: true)

Explanation: The input is a Container holding an i32. The specialized i32 implementation of display_details is called, printing the integer value and whether it's even.

Example 3:

Input:
let float_container = Container { value: 3.14 };
float_container.display_details();
Output:
Generic container holds: 3.14

Explanation: The input is a Container holding an f64. Since f64 doesn't have a specific specialization, the generic DisplayInfo implementation is used, leveraging the Debug trait.

Constraints

  • The Container struct must be generic over a single type parameter T.
  • The DisplayInfo trait must have exactly one method: display_details(&self).
  • The generic implementation of DisplayInfo should only apply when T implements std::fmt::Debug.
  • The specialized implementations must be for Container<String> and Container<i32> specifically.

Notes

This challenge directly relates to Rust's trait system and how it handles different implementations for the same trait based on concrete types. Pay close attention to the syntax for implementing traits for generic structs and for specific types within a generic context. You will likely need to use features like impl Trait for GenericStruct<SpecificType>.

Loading editor...
rust