Reusing an fmt::Formatter

In addition to using write! and format_args!, you can use various wrapper types to make it easier to work with the formatter (through the format traits). One of the most versatile ones is a combinator (Fmt below) that simply gives you access to the formatter in a closure:

use std::fmt;

pub struct Fmt<F>(pub F) where F: Fn(&mut fmt::Formatter) -> fmt::Result;

impl<F> fmt::Debug for Fmt<F>
    where F: Fn(&mut fmt::Formatter) -> fmt::Result
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        (self.0)(f)
    }
}

struct Mock {
    data: [i32; 40],
}

impl fmt::Debug for Mock {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Mock")
         .field("data", &Fmt(|f| f.debug_list().entries(self.data.iter()).finish()))
         .finish()
    }
}

fn main() {
    println!("{:#?}", Mock { data: [3; 40] } );
}

The full version of the Fmt formatter combinator would implement all the formatting traits, not just one of them.

1 Like