Skip to content

refactor(ui): a rule between two things belongs to nobody - #82

Merged
youhide merged 1 commit into
mainfrom
c1-one-rule
Aug 21, 2026
Merged

refactor(ui): a rule between two things belongs to nobody#82
youhide merged 1 commit into
mainfrom
c1-one-rule

Conversation

@youhide

@youhide youhide commented Aug 21, 2026

Copy link
Copy Markdown
Owner

C1. Twelve rules existed: nine horizontal under three different names — divider eight times, horizontal_rule once — and three vertical. Six of the nine were identical character for character.

Why this needed a module and not a delete key

They disagreed about two things, and only one of them was a real obstacle.

Their argument. Seven took &Palette; five took an iced::Color the caller had already pulled out of one. The colour form leaves every call site deciding what colour a rule is — precisely the decision that should not be made twelve times. So the shared one takes &Palette and a rule is always palette.border. Taking the colour away from the call site is most of the point: a container that is some other colour is not a rule, it is a band, and a band is a different thing with a different job.

Their message type. Some returned Element<Message>, some Element<RepoMessage>. This reads like the harder problem and is the easier one — a rule emits nothing, so the message type is free and the helpers are generic over it.

And their thickness was written three ways

Length::Fixed(1.0) on the space, 1 on the space, and Length::Fixed(1.0) on the container — all for the same line. It is metrics::HAIR now, which is what T1 was for.

The guard, and the guard's guard

The test reads the directory, not a list, so a widget added tomorrow is covered without anyone remembering to add it.

It has a second test that it reads anything at all. That is not padding: a source-scanning guard's real failure mode is walking an empty tree and passing forever. Sabotaging the directory list to [] leaves no_view_file_draws_its_own_rule passing and only the_guard_reads_every_view_file fails — which is exactly the case the second test exists for.

Sabotage — two, both confirmed

Sabotage What broke
blame.rs defines its own fn divider again no_view_file_draws_its_own_rule, naming the file
the guard walks no directories the_guard_reads_every_view_file — and the first test still passed

Scope

This settles the argument convention for the shared helpers only. The crate-wide split between &Palette and Palette by value still exists in the widgets' own signatures. It is not what stood in the way here, and changing every signature is a different change.

Screenshots

None retaken. Every rule is the same colour and thickness it already was — palette.border at 1px — so nothing on screen moved. The diff is 147 deletions against 169 insertions, most of the latter being the new module and its tests.

Docs

UI_SPEC.md's Layout scale section records where a rule lives, both reasons they could not be shared before, and why the colour is not a parameter.

Gate

cargo fmt --all -- --check, cargo clippy --workspace --all-targets --all-features --locked -- -D warnings, cargo test --workspace --all-features --locked — 898 tests, all green.

Twelve of them existed: nine horizontal under three different names — `divider`
eight times, `horizontal_rule` once — and three vertical. Six of the nine were
identical character for character.

They could not simply be shared, and the two reasons are worth naming because
they are why this is a module rather than a deletion.

They disagreed about their argument. Seven took `&Palette` and five took an
`iced::Color` the caller had already pulled out of one, which leaves each call
site deciding what colour a rule is — the decision that should not be made
twelve times. The answer is that a rule is always `palette.border`: taking the
colour away from the call site is most of the point, and a container that is any
other colour is not a rule but a band, which is a different thing with a
different job.

They also disagreed about their message type, some returning
`Element<Message>` and some `Element<RepoMessage>`. That reads like the harder
obstacle and is the easier one: a rule emits nothing, so the message type is
free and these are generic over it.

Their thickness is `metrics::HAIR` rather than a `1.0` written out three ways —
`Length::Fixed(1.0)` on the space, `1` on the space, and `Length::Fixed(1.0)` on
the container all appeared, for the same line.

The guard reads the directory rather than a list, so a widget added tomorrow is
covered without anyone remembering to add it, and it has a second test that it
reads anything at all — a guard that quietly walked an empty tree would pass
forever, which is the failure mode a source-scanning test actually has.

This settles the argument convention for the shared helpers only. The crate-wide
split between `&Palette` and `Palette` by value is still there, in the widgets'
own signatures, and is not what stood in the way here.
@youhide
youhide merged commit 0891b20 into main Aug 21, 2026
7 checks passed
@youhide
youhide deleted the c1-one-rule branch August 21, 2026 02:22
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.

1 participant