ratatui / ratatui

A Rust crate for cooking up terminal user interfaces (TUIs) 👨‍🍳🐀 https://ratatui.rs
https://ratatui.rs
MIT License
9.94k stars 303 forks source link

Debug formatting for Style, Span, Line, Text #1382

Open joshka opened 2 hours ago

joshka commented 2 hours ago

Problem

When writing some widget level code (for tui-markdown) and debugging the output of the text in tests, I found that having all fields in Style listed when they're None seemed overly verbose, and made it more difficult to navigate through any assertion errors (e.g. when taking a TDD approach to building things).

Additionally, the content field of the Span/Line/Text seems to dominate in size, as it's usually more complex than the other fields (style, alignment). This pushes them far below the start of the struct representation.

Solution

Alternatives

Write a function that provides a more custom compact debugging view of these methods:

fn compact_debug(&self) -> CompactDebugSpan {
...
}

impl Debug for CompactDebugSpan {
...
}

This doesn't work for assertions however, which use the Debug representation, so it seems like a non-starter.

Additional context

A real example from tui-markdown:

 Text {
     lines: [
         Line {
             spans: [
                 Span {
                     content: ">",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
                 Span {
                     content: " ",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
                 Span {
                     content: "Blockquote 1",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
             ],
             style: Style {
                 fg: Some(
                     Green,
                 ),
                 bg: None,
                 underline_color: None,
                 add_modifier: NONE,
                 sub_modifier: NONE,
             },
             alignment: None,
         },
         Line {
             spans: [
                 Span {
                     content: ">",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
                 Span {
                     content: ">",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
                 Span {
                     content: " ",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
                 Span {
                     content: "Nested Blockquote",
                     style: Style {
                         fg: None,
                         bg: None,
                         underline_color: None,
                         add_modifier: NONE,
                         sub_modifier: NONE,
                     },
                 },
             ],
             style: Style {
                 fg: Some(
                     Green,
                 ),
                 bg: None,
                 underline_color: None,
                 add_modifier: NONE,
                 sub_modifier: NONE,
             },
             alignment: None,
         },
     ],
     style: Style {
         fg: None,
         bg: None,
         underline_color: None,
         add_modifier: NONE,
         sub_modifier: NONE,
     },
     alignment: None,
 }

Which becomes after modification:

 Text {
    style: Style {},
    alignment: None,
    lines: [
         Line {
            style: Style { fg: Green, },
            alignment: None,
            spans: [
                 Span {
                     content: ">",
                     style: Style {},
                 },
                 Span {
                     content: " ",
                     style: Style {},
                 },
                 Span {
                     content: "Blockquote 1",
                     style: Style {},
                 },
             ],
         },
         Line {
            style: Style { fg: Green },
            alignment: None,
            spans: [
                 Span {
                     content: ">",
                     style: Style {},
                 },
                 Span {
                     content: ">",
                     style: Style {},
                 },
                 Span {
                     content: " ",
                     style: Style {},
                 },
                 Span {
                     content: "Nested Blockquote",
                     style: Style {},
                 },
             ],
         },
     ],
 }
joshka commented 1 hour ago

Omitting default values entirely, and collapsing spans that don't have non-default values to just a string:

 Text {
    lines: [
         Line {
            style: Style { fg: Green, },
            spans: [
                 Span { ">" },
                 Span { " " },
                 Span { "Blockquote 1" },
             ],
         },
         Line {
            style: Style { fg: Green },
            spans: [
                 Span { ">" },
                 Span { ">" },
                 Span { " " },
                 Span { "Nested Blockquote" },
             ],
         },
     ],
 }

110 lines -> 21 lines