// 083: Display Trait
// Implement Display for custom types
use std::fmt;
// Approach 1: Simple Display
#[derive(Debug)]
enum Color { Red, Green, Blue }
impl fmt::Display for Color {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Color::Red => write!(f, "Red"),
Color::Green => write!(f, "Green"),
Color::Blue => write!(f, "Blue"),
}
}
}
#[derive(Debug)]
struct Point { x: f64, y: f64 }
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:.1}, {:.1})", self.x, self.y)
}
}
// Approach 2: Complex formatting
#[derive(Debug)]
struct Person { name: String, age: u32, email: String }
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} (age {}, {})", self.name, self.age, self.email)
}
}
// Approach 3: Recursive Display
#[derive(Debug)]
enum Tree<T> { Leaf, Node(Box<Tree<T>>, T, Box<Tree<T>>) }
impl<T: fmt::Display> fmt::Display for Tree<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Tree::Leaf => write!(f, "."),
Tree::Node(l, v, r) => write!(f, "({} {} {})", l, v, r),
}
}
}
fn main() {
println!("{}", Color::Red);
println!("{}", Point { x: 3.0, y: 4.0 });
let p = Person { name: "Alice".into(), age: 30, email: "alice@ex.com".into() };
println!("{}", p);
println!("Debug: {:?}", p);
let tree = Tree::Node(
Box::new(Tree::Node(Box::new(Tree::Leaf), 1, Box::new(Tree::Leaf))),
2,
Box::new(Tree::Node(Box::new(Tree::Leaf), 3, Box::new(Tree::Leaf))),
);
println!("{}", tree);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_color_display() {
assert_eq!(format!("{}", Color::Red), "Red");
assert_eq!(format!("{}", Color::Green), "Green");
}
#[test]
fn test_point_display() {
assert_eq!(format!("{}", Point { x: 3.0, y: 4.0 }), "(3.0, 4.0)");
}
#[test]
fn test_person_display() {
let p = Person { name: "Alice".into(), age: 30, email: "alice@ex.com".into() };
assert_eq!(format!("{}", p), "Alice (age 30, alice@ex.com)");
}
#[test]
fn test_tree_display() {
let tree = Tree::Node(
Box::new(Tree::Node(Box::new(Tree::Leaf), 1, Box::new(Tree::Leaf))),
2,
Box::new(Tree::Node(Box::new(Tree::Leaf), 3, Box::new(Tree::Leaf))),
);
assert_eq!(format!("{}", tree), "((. 1 .) 2 (. 3 .))");
}
}
(* 083: Display โ custom string representation *)
(* Approach 1: Simple to_string *)
type color = Red | Green | Blue
let color_to_string = function
| Red -> "Red"
| Green -> "Green"
| Blue -> "Blue"
type point = { x: float; y: float }
let point_to_string p =
Printf.sprintf "(%.1f, %.1f)" p.x p.y
(* Approach 2: Complex formatting *)
type person = { name: string; age: int; email: string }
let person_to_string p =
Printf.sprintf "%s (age %d, %s)" p.name p.age p.email
let person_to_debug p =
Printf.sprintf "{ name = %S; age = %d; email = %S }" p.name p.age p.email
(* Approach 3: Recursive display *)
type 'a tree = Leaf | Node of 'a tree * 'a * 'a tree
let rec tree_to_string to_s = function
| Leaf -> "."
| Node (l, v, r) ->
Printf.sprintf "(%s %s %s)"
(tree_to_string to_s l)
(to_s v)
(tree_to_string to_s r)
(* Tests *)
let () =
assert (color_to_string Red = "Red");
assert (point_to_string { x = 3.0; y = 4.0 } = "(3.0, 4.0)");
let p = { name = "Alice"; age = 30; email = "alice@ex.com" } in
assert (person_to_string p = "Alice (age 30, alice@ex.com)");
let t = Node (Node (Leaf, 1, Leaf), 2, Node (Leaf, 3, Leaf)) in
assert (tree_to_string string_of_int t = "((. 1 .) 2 (. 3 .))");
Printf.printf "โ All tests passed\n"