Structured `Debug` output

This is one of the things that would really help me on occasion. Debug is really great, and the {:#?} alt version can help with moderately complex output, but when you are dumping really big structs to stdout, the output becomes unwieldy and hard to manage/navigate.

A few solutions come to mind:

  1. use serde and serialize to your favorite output type. This requires a big dependency and that all structs are annotated Serialize.
  2. Parse the textual output from Debug. There will be times when this fails (when the user implements debug themselves and deviates from the common patterns). It also requires work.

Is this a problem that other people have? How do you solve it? Is there an appetite for a Debug output parser?

1 Like

The docs explicitly mention somewhere that you are not supposed to do that. If you want predictable, regular, parseable output, use Display instead, which usually does involve hand-crafting an implementation.

Not sure why this is a problem. If you want to go back and forth between in-memory objects and a flat string, that is serialization/deserialization, and that's the very purpose of Serde. It exists because this problem is not trivially solvable without it. If you essentially need serialization, use a serialization library, simple as that.

4 Likes

I think you could make serde an optional dependency by making a serde feature for your crate. Then you could enable/disable at compile time your serde derives with #[cfg()] statements.
This way, you don't have to worry about requiring a big dependency when you don't need it. You'll compile it only when you need to do some debugging.

2 Likes

So doing this would only work some of the time. But if it doesn't work you haven't lost anything - you are back to just looking at the raw debug output.

I can't do this with structs that I use from other crates, tha impl Debug but not Serialize.

This is a good solution if you control all the types you want to debug.

There is:

You probably want the 1st one, but the other 2 could also work depending on your use case.

1 Like

That would work, but is a lot of work if you just want to debug.

Maybe the root of your problem can be avoided by manually implementing Debug and skipping/commenting out unnecessary fields.
That's actually a lot easier than it sound with the DebugStruct builder. You won't have full control because you don't control all the types you want to debug, but for your very large structs it could cut down on a lot of noise.


If that won't work either, then serde is the way to go: