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.