Skip to main content

max / makeover-layout

0.41.1: name nesting depth in a set, and not with the word Depth Decided in quasicoherent edf33114 (Max): this crate names the concept and makeover-webview writes the rule. RowPart already names what is IN a row -- Primary, Secondary, Meta, Actions, Tokens -- and nothing named where a row sits relative to its siblings, so every consumer with a hierarchy carried a bare number and every renderer decided for itself what one was worth. Nesting, not Depth. That word is taken here and means surface bevel: Flat, Raised, Well, Sunken, Overlay -- a fact about a surface rather than a position in a hierarchy. Two meanings under one word in one crate is the collision that costs a reader an hour, and it is the word this concept would otherwise want. The magnitude stays the renderer's, which is Awaiting's split exactly: this crate says a row is at level N, makeover-webview says what a level is worth as a custom property with a fallback, and a terminal spending columns for the same fact is not disagreeing. Zero is a real answer and the default -- a flat list is every row at the top level, which is true, and an Option here would make "not nested" and "nested at zero" two spellings of one thing. A PATCH, not the minor this crate has been taking for additions, and the task assumed the whole links cone would have to move with it. It does not: adding a type is semver-compatible, cargo unifies 0.41.0 and 0.41.1 to one version, and `links` only bites when a graph is asked for two. So no cone release, no forward fix, and every consumer picks it up on its next resolve with nothing to change.
Author: Max Johnson <me@maxj.phd> · 2026-08-30 23:49 UTC
Signed with PGP, not checked
Commit: d8f297402464c6b059160f7ed14ad06585e6eafe
Parent: 571614d
2 files changed, +87 insertions, -1 deletion
M Cargo.toml +1 -1
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "makeover-layout"
3 - version = "0.41.0"
3 + version = "0.41.1"
4 4 edition = "2024"
5 5 # One copy of this vocabulary per dependency graph, enforced by cargo rather
6 6 # than by remembering. Two versions of a description layer in one build means
M src/lib.rs +86
@@ -1320,6 +1320,74 @@
1320 1320 }
1321 1321 }
1322 1322
1323 + /// How deep a row sits inside a set: a tree, an outline, a threaded list.
1324 + ///
1325 + /// `edf33114`, decided 2026-08-30 (Max): this crate names the concept and
1326 + /// makeover-webview writes the rule. [`RowPart`] below already names what is
1327 + /// *in* a row; nothing named where a row sits relative to its siblings, so
1328 + /// every consumer that had a hierarchy carried a bare number and every renderer
1329 + /// decided for itself what one was worth.
1330 + ///
1331 + /// # Not `Depth`, and the collision is the reason
1332 + ///
1333 + /// [`Depth`] is taken and means something else entirely: surface bevel --
1334 + /// `Flat`, `Raised`, `Well`, `Sunken`, `Overlay` -- a fact about a surface
1335 + /// rather than a position in a hierarchy. Two meanings under one word in one
1336 + /// crate is the collision that costs a reader an hour, and the word this
1337 + /// concept wants is the one that would cause it.
1338 + ///
1339 + /// # The magnitude is the renderer's, and that is the precedent
1340 + ///
1341 + /// [`Awaiting`] is the shape: this crate names the fact and declines to name
1342 + /// what it is worth. makeover-webview writes the rule as a custom property with
1343 + /// a fallback -- the way it writes `margin-inline-start: var(--awaiting-gap,
1344 + /// 0.5ch)` -- so a level has one answer per renderer and an app can override
1345 + /// it. A terminal spends columns, a browser spends inline space, and neither
1346 + /// number belongs in a description.
1347 + ///
1348 + /// # Zero is a real answer
1349 + ///
1350 + /// [`top`](Self::top) is the default and is what a flat list says: every row is
1351 + /// at the top level, which is true and is the reading a renderer needs. An
1352 + /// `Option` here would make "not nested" and "nested at zero" two spellings of
1353 + /// one thing, the same argument `Discovery`'s `indexable` makes about defaults
1354 + /// that are meaningful.
1355 + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, PartialOrd, Ord)]
1356 + #[non_exhaustive]
1357 + pub struct Nesting {
1358 + /// How many levels in, counting from zero.
1359 + ///
1360 + /// `u8` because a hierarchy a reader can follow is not 256 deep, and a
1361 + /// renderer indenting by a level has to multiply it by something -- a wider
1362 + /// integer here is a wider integer in every renderer's arithmetic for a
1363 + /// range nothing will use.
1364 + pub level: u8,
1365 + }
1366 +
1367 + impl Nesting {
1368 + /// The top level: not nested. The default, and what a flat list says.
1369 + #[must_use]
1370 + pub const fn top() -> Self {
1371 + Self { level: 0 }
1372 + }
1373 +
1374 + /// A row this many levels in.
1375 + #[must_use]
1376 + pub const fn at(level: u8) -> Self {
1377 + Self { level }
1378 + }
1379 +
1380 + /// Whether this row sits under another.
1381 + ///
1382 + /// The question every renderer asks before it spends anything on indenting,
1383 + /// answered once here rather than by a `> 0` in each -- which is
1384 + /// [`Awaiting::is_determinate`]'s reason too.
1385 + #[must_use]
1386 + pub const fn is_nested(self) -> bool {
1387 + self.level > 0
1388 + }
1389 + }
1390 +
1323 1391 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1324 1392 #[non_exhaustive]
1325 1393 pub enum RowPart {
@@ -5758,6 +5826,24 @@
5758 5826
5759 5827 #[cfg(test)]
5760 5828 mod tests {
5829 + /// `edf33114`. The concept is named here and its magnitude is not, which is
5830 + /// `Awaiting`'s split and is why a renderer can disagree with another about
5831 + /// what a level is worth without either of them being wrong.
5832 + #[test]
5833 + fn nesting_says_how_deep_and_not_how_wide() {
5834 + assert_eq!(Nesting::default(), Nesting::top());
5835 + assert_eq!(Nesting::top().level, 0);
5836 + assert!(!Nesting::top().is_nested());
5837 +
5838 + let under = Nesting::at(2);
5839 + assert_eq!(under.level, 2);
5840 + assert!(under.is_nested());
5841 +
5842 + // Ordered, so a renderer walking a flat list of rows can compare two
5843 + // levels rather than reaching into the field.
5844 + assert!(Nesting::top() < under);
5845 + }
5846 +
5761 5847 use super::*;
5762 5848
5763 5849 #[test]