Overriding "alternate form" flags for Debug impls in deeply nested types

I have a type that has a map of vectors of pairs of ... and I'm implementing Debug manually to be able to provide better output than the default.

"Alternate form" (e.g. {:#?}) is really helpful to generate more readable output, but for this type it generates something like

{
    i0: [
        (
            i2,
            i4,
        ),
        (
            i0,
            i1,
        ),
    ],
    i1: [],
    i2: [
        (
            i2,
            i3,
        ),
    ],
    i3: [
        (
            i3,
            i4,
        ),
    ],
}

Ideally I want to generate

{
    i0: [ (i2, i4), (i0, i1) ],
    i1: [],
    i2: [ (i2, i3) ],
    i3: [ (i3, i4) ],
}

I don't care about trailing commas or whitespace around brackets -- I just want to use the compact layout for some parts, while using the alternate for for others. Is there a way to switch between these two modes in a Debug impl (in the fmt method) ?

Thanks.

If you use write!(f, "{:?}", self.0) then self.0 should be formatted without the alternate form flag set. If you are using f.debug_list(), then you could make a wrapper type that uses write!(f, "{:?}", self.0) in it's Debug impl.

For example

use std::fmt::*;

struct NoAlternate<T>(T);

impl<T: Debug> Debug for NoAlternate<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{:?}", self.0)
    }
}

struct List<T>(Vec<T>);

impl<T: Debug> Debug for List<T> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        f.debug_list().entries(self.0.iter().map(NoAlternate)).finish()
    }
}

fn main() {
    println!("{:#?}", List(vec![
        (1, 2),
        (3, 4),
    ]));
}

prints

[
    (1, 2),
    (3, 4),
]
1 Like

NoAlternate works great, thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.