add Deref to Repeatable

honestly, all the unwrapping was just generating noise.
This commit is contained in:
PgBiel 2025-04-20 15:18:31 -03:00
parent 9a01b9bfe8
commit 71ae276071
4 changed files with 32 additions and 27 deletions

View File

@ -238,9 +238,9 @@ impl<'a> GridLayouter<'a> {
while y < self.grid.rows.len() {
if let Some(next_header) = self.upcoming_headers.get(consecutive_header_count)
{
if next_header.unwrap().range().contains(&y) {
if next_header.range().contains(&y) {
self.place_new_headers(&mut consecutive_header_count, engine)?;
y = next_header.unwrap().end;
y = next_header.end;
// Skip header rows during normal layout.
continue;

View File

@ -18,9 +18,8 @@ impl<'a> GridLayouter<'a> {
if new_upcoming_headers.first().is_some_and(|next_header| {
consecutive_headers.last().is_none_or(|latest_header| {
!latest_header.unwrap().short_lived
&& next_header.unwrap().start == latest_header.unwrap().end
}) && !next_header.unwrap().short_lived
!latest_header.short_lived && next_header.start == latest_header.end
}) && !next_header.short_lived
}) {
// More headers coming, so wait until we reach them.
// TODO: refactor
@ -31,7 +30,7 @@ impl<'a> GridLayouter<'a> {
*consecutive_header_count = 0;
// Layout short-lived headers immediately.
if consecutive_headers.last().is_some_and(|h| h.unwrap().short_lived) {
if consecutive_headers.last().is_some_and(|h| h.short_lived) {
// No chance of orphans as we're immediately placing conflicting
// headers afterwards, which basically are not headers, for all intents
// and purposes. It is therefore guaranteed that all new headers have
@ -104,7 +103,7 @@ impl<'a> GridLayouter<'a> {
// Assuming non-conflicting headers sorted by increasing y, this must
// be the header with the lowest level (sorted by increasing levels).
let first_level = first_header.unwrap().level;
let first_level = first_header.level;
// Stop repeating conflicting headers.
// If we go to a new region before the pending headers fit alongside

View File

@ -1,5 +1,5 @@
use std::num::{NonZeroU32, NonZeroUsize};
use std::ops::Range;
use std::ops::{Deref, Range};
use std::sync::Arc;
use ecow::eco_format;
@ -487,6 +487,14 @@ pub enum Repeatable<T> {
NotRepeated(T),
}
impl<T> Deref for Repeatable<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.unwrap()
}
}
impl<T> Repeatable<T> {
/// Gets the value inside this repeatable, regardless of whether
/// it repeats.
@ -1562,10 +1570,10 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
let mut consecutive_header_start = data.start;
for conflicting_header in
headers.iter_mut().rev().take_while(move |h| {
let conflicts = h.unwrap().end == consecutive_header_start
&& h.unwrap().level >= data.level;
let conflicts = h.end == consecutive_header_start
&& h.level >= data.level;
consecutive_header_start = h.unwrap().start;
consecutive_header_start = h.start;
conflicts
})
{
@ -1818,8 +1826,7 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// TODO: will need a global slice of headers and footers for
// when we have multiple footers
let last_header_end =
headers.last().map(Repeatable::unwrap).map(|header| header.end);
let last_header_end = headers.last().map(|header| header.end);
if has_gutter {
// Convert the footer's start index to post-gutter coordinates.
@ -1860,11 +1867,11 @@ impl<'x> CellGridResolver<'_, '_, 'x> {
// final footer, as short lived, given that there are no normal rows
// after them, so repeating them is pointless.
let mut consecutive_header_start =
footer.as_ref().map(|f| f.unwrap().start).unwrap_or(row_amount);
footer.as_ref().map(|f| f.start).unwrap_or(row_amount);
for header_at_the_end in headers.iter_mut().rev().take_while(move |h| {
let at_the_end = h.unwrap().end == consecutive_header_start;
let at_the_end = h.end == consecutive_header_start;
consecutive_header_start = h.unwrap().start;
consecutive_header_start = h.start;
at_the_end
}) {
header_at_the_end.unwrap_mut().short_lived = true;
@ -2052,9 +2059,10 @@ fn check_for_conflicting_cell_row(
// `y + 1 = header.start` holds, that means `y < header.start`, and it
// only occupies one row (`y`), so the cell is actually not in
// conflict.
if headers.iter().any(|header| {
cell_y < header.unwrap().end && cell_y + rowspan > header.unwrap().start
}) {
if headers
.iter()
.any(|header| cell_y < header.end && cell_y + rowspan > header.start)
{
bail!(
"cell would conflict with header spanning the same position";
hint: "try moving the cell or the header"
@ -2248,11 +2256,9 @@ fn find_next_available_position<const SKIP_ROWS: bool>(
}
// TODO: consider keeping vector of upcoming headers to make this check
// non-quadratic (O(cells) instead of O(headers * cells)).
} else if let Some(header) =
headers.iter().map(Repeatable::unwrap).find(|header| {
} else if let Some(header) = headers.iter().find(|header| {
(header.start * columns..header.end * columns).contains(&resolved_index)
})
{
}) {
// Skip header (can't place a cell inside it from outside it).
resolved_index = header.end * columns;

View File

@ -293,13 +293,13 @@ fn show_cellgrid_html(grid: CellGrid, styles: StyleChain) -> Content {
};
let footer = grid.footer.map(|ft| {
let rows = rows.drain(ft.unwrap().start..);
let rows = rows.drain(ft.start..);
elem(tag::tfoot, Content::sequence(rows.map(|row| tr(tag::td, row))))
});
// TODO: Headers and footers in arbitrary positions
// Right now, only those at either end are accepted
let header = grid.headers.first().filter(|h| h.unwrap().start == 0).map(|hd| {
let rows = rows.drain(..hd.unwrap().end);
let header = grid.headers.first().filter(|h| h.start == 0).map(|hd| {
let rows = rows.drain(..hd.end);
elem(tag::thead, Content::sequence(rows.map(|row| tr(tag::th, row))))
});