Currently, I can't find a way to implement nested indentation with Formatter
. The standard library's DebugMap
and DebugStruct
does so via an internal PadAdapter
, which you can't implement yourself because it touches private fields of Formatter
. I think the standard library should add a way that allows users to write adapters like PadAdapter
, either by simply making wrap_buf
public or by some other mechanisms.
It's new to me that this is not possible, because we are doing this in diesel since some time.
Diesel only implements the part of PadAdapter
that is responsible for indentation. This is sufficient in this case.
However, Debug*
structures essentially clone a Formatter
while substituting a Write
implementation. For instance, consider the following program:
#[derive(Debug)]
struct Hi {
field: i32,
}
fn main() {
println!("{:_>#10?}", Hi { field: 33 })
}
Outputs:
Hi {
field: ________33,
}
In this case, the width parameter of a formatter is passed through.
Just as @xfix said, an implementation like diesel
's contains only the methods provided by fmt::Write
trait, whereas std
's implementation basically swaps out the underlying buffer (a trait object of fmt::Write
) with a custom trait object. This way, not only that the interface of Formatter
is preserved, any calls to any methods on Formatter
will go through your custom trait object.
I'm not sure this is what you need but I wrote indentation for anyhow
and extracted it into a crate here https://docs.rs/indenter/0.1.3/indenter/ where you wrap a formatter with another object that impls fmt::Write and it handles detecting newlines and inserting the indentation after each newline.
The specific implementation is only really setup to handle the one tier of indentation needed by when running Display::fmt
on an error but it might be possible to extend it to fit your needs, and I'd be happy to add features you need back to the library to make it more generally useful.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.