| 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 |
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]
|