println! structs

So we’ve got ourselves a simply little struct

struct Point {
    x: i32,
    y: i32
}

We then decide that we’d like to output the current state of the Point using println!, so we write

fn main() {
    let p = Point { x: 20, y: 3 };

    println!("{}", p);
}

Running this will result in `Point` doesn’t implement `std::fmt::Display` and `Point` cannot be formatted with the default formatter. In fact we do not really need to implement std::fmt::Display, we can just annotate our struct with #[derive(Debug)] and then use the println! formatters (:? or :#?), for example

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32
}

fn main() {
    let p = Point { x: 20, y: 3 };

    println!("{:?}", p);
}

The use of :? will result in the following output Point { x: 20, y: 3 } whereas :#? will display the values on lines of their own (a “prettier” formatter). Both :? and :#? are debug formatters, hence require the annotation #[derive(Debug)] or we can implement std::fmt::Debug, for example

impl std::fmt::Debug for Point {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "(x is {}, y is {})", self.x, self.y)
    }
}

For situations where we simply want to create our own custom display (not just for Debug), then, as per the original error `Point` doesn’t implement `std::fmt::Display`, we would need to implement the std::fmt::Display trait, i.e.

impl std::fmt::Display for Point {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "(x is {}, y is {})", self.x, self.y)
    }
}

This means we no longer requiring the annotation or special formatters, hence our full code will look like this

struct Point {
    x: i32,
    y: i32
}

impl std::fmt::Display for Point {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "(x is {}, y is {})", self.x, self.y)
    }
}

fn main() {
    let p = Point { x: 20, y: 3 };

    println!("{}", p);
}

and as you’d expect our output is now (x is 20, y is 3).