Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a dbg! alternative in Rust which doesn't break tuples into so many lines?

Tags:

debugging

rust

I'm doing good old debug driven programming and I keep having readability issues because all tuples and structs get split up into million rows. Is there a way to somehow get a more compact dbg output?

e.g. I get from dbg!

[asd/src/data_source.rs:330] &lines[0] = InfluxLine {
    line_name: "line",
    tags: [
        (
            "label",
            "\"All\"",
        ),
        (
            "source",
            "wer",
        ),
        (
            "query",
            "reach_per_mode_hourly",
        ),
        (
            "query_type",
            "hourly_averages_coeff",
        ),
        (
            "measure_name",
            "reach",
        ),
    ],

Ideally this would be

[asd/src/data_source.rs:330] &lines[0] = InfluxLine {
    line_name: "line",
    tags: [
        ( "label", "\"All\"", ),
        ( "source", "wer", ),
        ( "query", "reach_per_mode_hourly", ),
        ( "query_type", "hourly_averages_coeff", ),
        ( "measure_name", "reach", ),
    ],
like image 464
ditoslav Avatar asked Dec 22 '20 13:12

ditoslav


People also ask

What is DBG in Rust?

Prints and returns the value of a given expression for quick and dirty debugging. An example: let a = 2; let b = dbg!(


2 Answers

You can implement Debug manually to have full control over the formatting used by dbg. You can create a struct that holds a value and always formats it without pretty printing:

struct NoPrettyPrint<T: Debug>(T);

impl<T> Debug for NoPrettyPrint<T> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        // {:#?} never used here even if dbg!() specifies it
        write!(f, "{:?}", self.0)
    }
}

Use Formatter::debug_struct to manually implement Debug for InfluxLine:

impl Debug for InfluxLine {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        let tags: Vec<_> = self.tags.iter().map(NoPrettyPrint).collect();
        fmt.debug_struct("InfluxLine")
            .field("line_name", &self.line_name)
            .field("tags", &tags),
            .finish()
    }
}
like image 89
Dull Bananas Avatar answered Sep 27 '22 19:09

Dull Bananas


As you showed what you want is that the pretty print does not apply to the tuples, one way that occurs to me to do that is to create a structure that implements the debug trait but this structure will only contain the tuple.

struct TupleDebug((String, String));
impl fmt::Debug for TupleDebug {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{:?}", self.0)
    }
}

...

let tuple_list = vec![
    TupleDebug(("asd".to_string(), "fefefe".to_string())),
    TupleDebug(("asd".to_string(), "fefefe".to_string())),
    TupleDebug(("asd".to_string(), "fefefe".to_string())),
    TupleDebug(("asd".to_string(), "fefefe".to_string())),
];
dbg!(tuple_list);

Result:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.76s
     Running `target/debug/playground`
[src/main.rs:17] tuple_list = [
    ("asd", "fefefe"),
    ("asd", "fefefe"),
    ("asd", "fefefe"),
    ("asd", "fefefe"),
]

Or Just use format!() and pass the formatted text to dbg!(), but all the text will be output on a single line:

let tuple_list = vec![
    ("asd".to_string(), "fefefe".to_string()),
    ("asd".to_string(), "fefefe".to_string()),
    ("asd".to_string(), "fefefe".to_string()),
    ("asd".to_string(), "fefefe".to_string()),
];
let debug_tuple_list = format!("{:?}", tuple_list);
dbg!(debug_tuple_list);

Result:

   Compiling playground v0.0.1 (/playground)
    Finished dev [unoptimized + debuginfo] target(s) in 0.76s
     Running `target/debug/playground`
[src/main.rs:17] format!("{:?}", tuple_list) = "[(\"asd\", \"fefefe\"), (\"asd\", \"fefefe\"), (\"asd\", \"fefefe\"), (\"asd\", \"fefefe\")]"
like image 20
NemuiSen Avatar answered Sep 27 '22 19:09

NemuiSen