Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(widgets): Implement Debug & Default common traits #339

Merged
merged 1 commit into from
Jul 27, 2023

Conversation

TieWay59
Copy link
Contributor

@TieWay59 TieWay59 commented Jul 21, 2023

Implement Debug & Default common traits for most structs in src.

Reorder the derive fields to be more consistent:

Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash

see: #307

@codecov
Copy link

codecov bot commented Jul 21, 2023

Codecov Report

Merging #339 (20088d2) into main (b9290b3) will decrease coverage by 0.38%.
The diff coverage is 67.44%.

@@            Coverage Diff             @@
##             main     #339      +/-   ##
==========================================
- Coverage   85.08%   84.70%   -0.38%     
==========================================
  Files          40       40              
  Lines        8608     8605       -3     
==========================================
- Hits         7324     7289      -35     
- Misses       1284     1316      +32     
Impacted Files Coverage Δ
src/terminal.rs 55.73% <0.00%> (-0.47%) ⬇️
src/text/masked.rs 98.64% <0.00%> (ø)
src/widgets/calendar.rs 81.06% <0.00%> (-1.25%) ⬇️
src/widgets/clear.rs 0.00% <0.00%> (ø)
src/widgets/reflow.rs 98.42% <0.00%> (-0.39%) ⬇️
src/widgets/sparkline.rs 89.26% <0.00%> (ø)
src/widgets/tabs.rs 75.00% <0.00%> (ø)
src/symbols.rs 46.15% <46.15%> (+21.15%) ⬆️
src/widgets/scrollbar.rs 87.71% <50.00%> (ø)
src/layout.rs 89.40% <62.50%> (-0.67%) ⬇️
... and 17 more

@TieWay59
Copy link
Contributor Author

Hey @joshka, I've been doing this today. And I wish to share my discoveries with you before more next step of review.

  1. I can't split these files into four PR, because many of them are related (for example, if A deps on B, then we need B to have some C-Trait, then, add it to A.) So this is a huge one hard to review, if you have any idea on splitting this up, let me know if possible.
  2. I following an intention to give as many common traits as we can, in order of:
  3. But.. Copy trait might be implicitly memory-costing if have it around too much.
  4. Display is more difficult to design for every struct, so I never actively add it.
  5. Some Default impl can be replaced by derive if every member has a Default trait already, I tried some cases, and I wonder if it's necessary to write a test case for it.
  6. Ord, and PartialOrd, might seem redundant but I add them all the way if it's possible.

@TieWay59 TieWay59 marked this pull request as draft July 21, 2023 09:38
@orhun orhun changed the title [WIP] Chore: implement common traits Part 1 chore(widgets): implement common traits Jul 21, 2023
Copy link
Member

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM generally - I'll answer the question comments in the conversation

My main suggestion is to remove the Eq/PartialEq where it doesn't seem to make sense (unless you think we need it for some reason).

src/buffer.rs Outdated Show resolved Hide resolved
src/layout.rs Outdated Show resolved Hide resolved
src/layout.rs Outdated Show resolved Hide resolved
src/symbols.rs Outdated Show resolved Hide resolved
src/symbols.rs Outdated Show resolved Hide resolved
src/widgets/gauge.rs Outdated Show resolved Hide resolved
@joshka
Copy link
Member

joshka commented Jul 22, 2023

Hey @joshka, I've been doing this today. And I wish to share my discoveries with you before more next step of review.

Nice

1. I can't split these files into four PR, because many of them are related (for example, if A deps on B, then we need B to have some C-Trait, then, add it to A.) So this is a huge one hard to review, if you have any idea on splitting this up, let me know if possible.

Makes sense, I'd even prefer to see a single commit if the split commits don't compile (as it makes it easier to git bisect if every commit compiles). No big deal on this as the merge will probably join the commits, but doesn't hurt.

2. I following an intention to give as many common traits as we can, in  order of:
   
   * [Copy](https://doc.rust-lang.org/std/marker/trait.Copy.html)
   * [Clone](https://doc.rust-lang.org/std/clone/trait.lone.html)
   * [Eq](https://doc.rust-lang.org/std/cmp/trait.Eq.html)
   * [PartialEq](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
   * [Ord](https://doc.rust-lang.org/std/cmp/trait.Ord.html)
   * [PartialOrd](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html)
   * [Hash](https://doc.rust-lang.org/std/hash/trait.Hash.html)
   * [Debug](https://doc.rust-lang.org/std/fmt/trait.Debug.html)
   * [Display](https://doc.rust-lang.org/std/fmt/trait.Display.html)
   * [Default](https://doc.rust-lang.org/std/default/trait.Default.html)

Note my comment about ordering. Of these, I'd probably say that Debug and Default are the two most important, followed by Clone and Copy. Being able to glance at a derives list and see that these are implemented is something I personally often rely on. Small nit but useful I think.

3. But.. `Copy` trait might be implicitly memory-costing if have it around too much.

Can you point out the impact of any problems you might see with this?

4. `Display` is more difficult to design for every struct, so I never actively add it.

Let's defer Display to another PR?

5. Some `Default impl` can be replaced by derive if every member has a `Default` trait already, I tried some cases, and I wonder if it's necessary to write a test case for it.

It's probably worthwhile adding default tests as it helps catch any future changes in the defaults that are accidentally made.

6. `Ord`, and `PartialOrd`, might seem redundant but I add them all the way if it's possible.

Perhaps these should not be implemented except for where it's necessary? Is there better guidance on this available? Are there use cases where having these makes things easier to implement that aren't obvious?

@TieWay59
Copy link
Contributor Author

@joshka Now my PR is focused on Debug & Default trait, I hope this shift can make you feel better while reviewing. And I also reordered some old patterns to align with the preferred traits order.

Copy link
Member

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - just one question that is not blocking.

src/widgets/gauge.rs Show resolved Hide resolved
@TieWay59
Copy link
Contributor Author

@joshka About the coverage, Should I write a test for every struct? I found it would be very huge, and since there are still many old codes that don't have coverage before me, I'd like to hear your idea.

It's OK if you feel this is necessary. But I have to warn that, since we don't have much PartialEq trait, I may have to write cases like:

        assert_eq!(
            format!("{:?}", LineGauge::default()),
            format!(
                "{:?}",
                LineGauge {
                    block: None,
                    ratio: 0.0,
                    label: None,
                    style: Style::default(),
                    line_set: symbols::line::NORMAL,
                    gauge_style: Style::default(),
                }
            ),
            "LineGauge::default() should have correct default values."
        );

(Yes, it looks weird. it's my workaround, please guide me if you have a better suggestion ❤️ )

@TieWay59
Copy link
Contributor Author

Sorry I pushed again, I found one struct I missed, and I give a shorter name for the default test.

@TieWay59 TieWay59 requested a review from joshka July 26, 2023 02:54
@TieWay59 TieWay59 marked this pull request as ready for review July 26, 2023 02:59
@TieWay59 TieWay59 requested a review from kdheepak as a code owner July 26, 2023 02:59
@TieWay59 TieWay59 changed the title chore(widgets): implement common traits chore(widgets): Implement Debug & Default common traits Jul 26, 2023
@joshka
Copy link
Member

joshka commented Jul 26, 2023

I'd say that adding coverage on the derived traits can probably be deferred. I'll leave that up for whoever does the second review on this.

@kdheepak
Copy link
Collaborator

I don't have a blocking review, but I was curious what the impact on library size (or binary size) this has. Is there some metrics you can add to the PR description?

@joshka
Copy link
Member

joshka commented Jul 27, 2023

I don't have a blocking review, but I was curious what the impact on library size (or binary size) this has. Is there some metrics you can add to the PR description?

This is pretty much zero.
I check on the debug build one of the examples shows up in the debug builds as 4KB extra on a 3.8MB binary. The release mode build is the exact same size. I'd assume most use cases will never care about binary size for this sort of thing, but if there's something obvious I'm missing...

Implement `Debug & Default` common traits for most structs in src.

Reorder the derive fields to be more consistent:

    Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash

see: ratatui#307
@joshka
Copy link
Member

joshka commented Jul 27, 2023

The scrollbar::Set type moved to symbols::scrollbar::Set. I updated the commit with that change (just needs an approval to merge).

Thanks for submitting this PR. It's something that I have run into a few times (particularly Debug being missing).

@joshka joshka added this pull request to the merge queue Jul 27, 2023
Merged via the queue into ratatui:main with commit bf49446 Jul 27, 2023
27 of 28 checks passed
@TieWay59 TieWay59 deleted the tieway59_dev branch July 27, 2023 04:01
@joshka
Copy link
Member

joshka commented Jul 27, 2023

P.s. to make future PRs easier for us merge, can you please setup commit signing?
See https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

@joshka joshka added this to the v0.23.0 milestone Aug 21, 2023
joshka added a commit that referenced this pull request Jan 5, 2024
In #660 we introduced the
segment_size field to the Table struct. However, we forgot to update
the default() implementation to match the new() implementation. This
meant that the default() implementation picked up SegmentSize::default()
instead of SegmentSize::None.

Additionally the introduction of Table::default() in an earlier PR,
#339, was also missing the
default for the column_spacing field (1).

This commit fixes the default() implementation to match the new()
implementation of these two fields by implementing the Default trait
manually.

BREAKING CHANGE: The default() implementation of Table now sets the
column_spacing field to 1 and the segment_size field to
SegmentSize::None. This will affect the rendering of a small amount of
apps.
joshka added a commit that referenced this pull request Jan 5, 2024
In #660 we introduced the
segment_size field to the Table struct. However, we forgot to update
the default() implementation to match the new() implementation. This
meant that the default() implementation picked up SegmentSize::default()
instead of SegmentSize::None.

Additionally the introduction of Table::default() in an earlier PR,
#339, was also missing the
default for the column_spacing field (1).

This commit fixes the default() implementation to match the new()
implementation of these two fields by implementing the Default trait
manually.

BREAKING CHANGE: The default() implementation of Table now sets the
column_spacing field to 1 and the segment_size field to
SegmentSize::None. This will affect the rendering of a small amount of
apps.
Valentin271 pushed a commit that referenced this pull request Jan 10, 2024
In #660 we introduced the
segment_size field to the Table struct. However, we forgot to update
the default() implementation to match the new() implementation. This
meant that the default() implementation picked up SegmentSize::default()
instead of SegmentSize::None.

Additionally the introduction of Table::default() in an earlier PR,
#339, was also missing the
default for the column_spacing field (1).

This commit fixes the default() implementation to match the new()
implementation of these two fields by implementing the Default trait
manually.

BREAKING CHANGE: The default() implementation of Table now sets the
column_spacing field to 1 and the segment_size field to
SegmentSize::None. This will affect the rendering of a small amount of
apps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants