Why is the width ignored for my custom formatter implementation?

Viewed 483

When I have an enum with Display implemented and I try to print it formatted, the width I give it is ignored.

use std::fmt;
enum TestEnum {
    A,
    B,
}

impl fmt::Display for TestEnum {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            TestEnum::A => write!(f, "A"),
            TestEnum::B => write!(f, "B"),
        }
    }
}

fn main() {
    println!("-{value:>width$}-", value = TestEnum::A, width = 3);
}

I expect it to output - A-, but it outputs -A-.

If I replace the value with the actual string instead of the enum, it does the right thing,

println!("-{value:>width$}-", value = "A", width = 3);

outputs

-  A-

Why is the width being ignored? What do I need to do differently?

1 Answers

By using write! in your fmt implementation, you are overriding the format provided by its caller.

Instead you should call fmt on the strings themselves:

impl fmt::Display for TestEnum {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            TestEnum::A => "A".fmt(f),
            TestEnum::B => "B".fmt(f),
        }
    }
}

(Permalink to the playground)

This will correctly print - A-.

Related