work
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 2 Dec 2025 17:02:15 +0000 (09:02 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 2 Dec 2025 17:02:15 +0000 (09:02 -0800)
rust/pspp/src/output/drivers/csv.rs
rust/pspp/src/output/drivers/html.rs
rust/pspp/src/output/pivot.rs
rust/pspp/src/output/pivot/output.rs
rust/pspp/src/output/render.rs
rust/pspp/src/output/table.rs
rust/pspp/src/settings.rs

index 738f50e73f21daace877399ab2e67d6d8d9c6291..498dd744630ed444eaf7d3bb6283ec61db743e12 100644 (file)
@@ -31,9 +31,7 @@ use crate::{
     data::{ByteString, Case, Datum, WithEncoding},
     dictionary::Dictionary,
     format::{DisplayPlain, Type},
-    output::{
-        drivers::Driver, table::CellPos, Item
-    },
+    output::{Item, drivers::Driver, table::CellPos},
     util::ToSmallString as _,
     variable::Variable,
 };
@@ -328,13 +326,13 @@ impl CsvDriver {
             return Ok(());
         };
 
-        for y in 0..table.n.y() {
-            for x in 0..table.n.x() {
+        for y in 0..table.n.1 {
+            for x in 0..table.n.0 {
                 if x > 0 {
                     write!(&mut self.file, "{}", self.options.delimiter)?;
                 }
 
-                let coord = CellPos::new(x, y);
+                let coord = CellPos(x, y);
                 let content = table.get(coord);
                 if content.is_top_left() {
                     let display = content.inner().value.display(pivot_table);
index e0d2b9245cc4927a1f81a0f213e63e77e4120feb..2172cc0a0d30c0de36607484042cdb2cfb17aa00 100644 (file)
@@ -27,9 +27,10 @@ use serde::{Deserialize, Serialize};
 use smallstr::SmallString;
 
 use crate::output::{
-    drivers::Driver, pivot::{
-        Axis2, BorderStyle, Color, HorzAlign, IndexRect2, PivotTable, Stroke, VertAlign
-    }, table::{DrawCell, CellPos, Table}, Details, Item
+    Details, Item,
+    drivers::Driver,
+    pivot::{Axis2, BorderStyle, Color, HorzAlign, PivotTable, Stroke, VertAlign},
+    table::{CellPos, CellRect, DrawCell, Table},
 };
 
 #[derive(Clone, Debug, Deserialize, Serialize)]
@@ -85,10 +86,10 @@ where
             writeln!(&mut self.writer, ">")?;
 
             if let Some(title) = output.title {
-                let cell = title.get(CellPos::new(0, 0));
+                let cell = title.get(CellPos(0, 0));
                 self.put_cell(
                     DrawCell::new(cell.inner(), &title),
-                    IndexRect2::new(0..1, 0..1),
+                    CellRect::new(0..1, 0..1),
                     "caption",
                     None,
                 )?;
@@ -100,7 +101,7 @@ where
                     writeln!(&mut self.writer, "<tr>")?;
                     self.put_cell(
                         DrawCell::new(cell.inner(), &layers),
-                        IndexRect2::new(0..output.body.n[Axis2::X], 0..1),
+                        CellRect::new(0..output.body.n[Axis2::X], 0..1),
                         "td",
                         None,
                     )?;
@@ -110,10 +111,10 @@ where
             }
 
             writeln!(&mut self.writer, "<tbody>")?;
-            for y in 0..output.body.n.y() {
+            for y in 0..output.body.n.1 {
                 writeln!(&mut self.writer, "<tr>")?;
                 for x in output.body.iter_x(y) {
-                    let cell = output.body.get(CellPos::new(x, y));
+                    let cell = output.body.get(CellPos(x, y));
                     if cell.is_top_left() {
                         let is_header = x < output.body.h[Axis2::X] || y < output.body.h[Axis2::Y];
                         let tag = if is_header { "th" } else { "td" };
@@ -134,8 +135,8 @@ where
                 writeln!(&mut self.writer, "<tr>")?;
                 if let Some(caption) = output.caption {
                     self.put_cell(
-                        DrawCell::new(caption.get(CellPos::new(0, 0)).inner(), &caption),
-                        IndexRect2::new(0..output.body.n[Axis2::X], 0..1),
+                        DrawCell::new(caption.get(CellPos(0, 0)).inner(), &caption),
+                        CellRect::new(0..output.body.n[Axis2::X], 0..1),
                         "td",
                         None,
                     )?;
@@ -147,7 +148,7 @@ where
                         writeln!(&mut self.writer, "<tr>")?;
                         self.put_cell(
                             DrawCell::new(cell.inner(), &footnotes),
-                            IndexRect2::new(0..output.body.n[Axis2::X], 0..1),
+                            CellRect::new(0..output.body.n[Axis2::X], 0..1),
                             "td",
                             None,
                         )?;
@@ -163,7 +164,7 @@ where
     fn put_cell(
         &mut self,
         cell: DrawCell<'_, '_>,
-        rect: IndexRect2,
+        rect: CellRect,
         tag: &str,
         table: Option<&Table>,
     ) -> std::io::Result<()> {
@@ -234,20 +235,14 @@ where
             if rect[Axis2::X].end == table.n[Axis2::X] {
                 Self::put_border(
                     &mut style,
-                    table.get_rule(
-                        Axis2::X,
-                        CellPos::new(rect[Axis2::X].end, rect[Axis2::Y].start),
-                    ),
+                    table.get_rule(Axis2::X, CellPos(rect[Axis2::X].end, rect[Axis2::Y].start)),
                     "right",
                 );
             }
             if rect[Axis2::Y].end == table.n[Axis2::Y] {
                 Self::put_border(
                     &mut style,
-                    table.get_rule(
-                        Axis2::Y,
-                        CellPos::new(rect[Axis2::X].start, rect[Axis2::Y].end),
-                    ),
+                    table.get_rule(Axis2::Y, CellPos(rect[Axis2::X].start, rect[Axis2::Y].end)),
                     "bottom",
                 );
             }
index 756098f173c25304adcb5589279469a43d1ee0b8..1b7f3672afa640f394552257186f2db6a48fae09 100644 (file)
@@ -76,9 +76,10 @@ use crate::{
     calendar::date_time_to_pspp,
     data::{ByteString, Datum, EncodedString},
     format::{
-        Decimal, Format, Settings as FormatSettings, Type, UncheckedFormat, DATETIME40_0, F40, F40_2, F40_3, F8_2, PCT40_1
+        DATETIME40_0, Decimal, F8_2, F40, F40_2, F40_3, Format, PCT40_1,
+        Settings as FormatSettings, Type, UncheckedFormat,
     },
-    output::{spv::html::Markup, table::CellPos},
+    output::spv::html::Markup,
     settings::{Settings, Show},
     util::ToSmallString,
     variable::{VarType, Variable},
@@ -1723,64 +1724,6 @@ impl IndexMut<Axis2> for Rect2 {
     }
 }
 
-#[derive(Clone, Debug, Default)]
-pub struct IndexRect2(pub EnumMap<Axis2, Range<usize>>);
-
-impl IndexRect2 {
-    pub fn new(x_range: Range<usize>, y_range: Range<usize>) -> Self {
-        Self(enum_map! {
-            Axis2::X => x_range.clone(),
-            Axis2::Y => y_range.clone(),
-        })
-    }
-    pub fn for_cell(cell: CellPos) -> Self {
-        Self::new(cell.x()..cell.x() + 1, cell.y()..cell.y() + 1)
-    }
-    pub fn for_ranges((a, a_range): (Axis2, Range<usize>), b_range: Range<usize>) -> Self {
-        let b = !a;
-        let mut ranges = EnumMap::default();
-        ranges[a] = a_range;
-        ranges[b] = b_range;
-        Self(ranges)
-    }
-    pub fn top_left(&self) -> CellPos {
-        use Axis2::*;
-        CellPos::new(self[X].start, self[Y].start)
-    }
-    pub fn from_fn<F>(f: F) -> Self
-    where
-        F: FnMut(Axis2) -> Range<usize>,
-    {
-        Self(EnumMap::from_fn(f))
-    }
-    pub fn translate(self, offset: CellPos) -> IndexRect2 {
-        Self::from_fn(|axis| self[axis].start + offset[axis]..self[axis].end + offset[axis])
-    }
-    pub fn is_empty(&self) -> bool {
-        self[Axis2::X].is_empty() || self[Axis2::Y].is_empty()
-    }
-}
-
-impl From<EnumMap<Axis2, Range<usize>>> for IndexRect2 {
-    fn from(value: EnumMap<Axis2, Range<usize>>) -> Self {
-        Self(value)
-    }
-}
-
-impl Index<Axis2> for IndexRect2 {
-    type Output = Range<usize>;
-
-    fn index(&self, index: Axis2) -> &Self::Output {
-        &self.0[index]
-    }
-}
-
-impl IndexMut<Axis2> for IndexRect2 {
-    fn index_mut(&mut self, index: Axis2) -> &mut Self::Output {
-        &mut self.0[index]
-    }
-}
-
 #[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
 #[serde(rename_all = "camelCase")]
 pub enum FootnoteMarkerType {
index a37f0cbda4c7fadbad9ca54600d70876f2f91212..8610277d4a0542bd89b8b8203f5f44bb4f967a4e 100644 (file)
@@ -20,8 +20,8 @@ use enum_map::{EnumMap, enum_map};
 use itertools::Itertools;
 
 use crate::output::{
-    pivot::{HeadingRegion, IndexRect2, LabelPosition, Path, RowParity},
-    table::{CellInner, CellPos, Table},
+    pivot::{HeadingRegion, LabelPosition, Path, RowParity},
+    table::{CellInner, CellPos, CellRect, Table},
 };
 
 use super::{
@@ -139,17 +139,14 @@ impl PivotTable {
         I: Iterator<Item = Box<Value>> + ExactSizeIterator,
     {
         let mut table = Table::new(
-            CellPos::new(1, rows.len()),
-            CellPos::new(0, 0),
+            CellPos(1, rows.len()),
+            CellPos(0, 0),
             self.style.look.areas.clone(),
             self.borders(false),
             self.into_value_options(),
         );
         for (y, row) in rows.enumerate() {
-            table.put(
-                IndexRect2::for_cell(CellPos::new(0, y)),
-                CellInner::new(area, row),
-            );
+            table.put(CellRect::for_cell(CellPos(0, y)), CellInner::new(area, row));
         }
         table
     }
@@ -180,7 +177,7 @@ impl PivotTable {
 
         let data = CellPos::from_fn(|axis| headings[axis].width());
         let mut stub = CellPos::from_fn(|axis| headings[!axis].height());
-        if headings[Axis2::Y].row_label_position == LabelPosition::Corner && stub.y() == 0 {
+        if headings[Axis2::Y].row_label_position == LabelPosition::Corner && stub.1 == 0 {
             stub[Axis2::Y] = 1;
         }
         let mut body = Table::new(
@@ -205,7 +202,7 @@ impl PivotTable {
                 let data_indexes = self.convert_indexes_ptod(presentation_indexes);
                 let value = self.get(&*data_indexes);
                 body.put(
-                    IndexRect2::new(x..x + 1, y..y + 1),
+                    CellRect::new(x..x + 1, y..y + 1),
                     CellInner::new(
                         Area::Data(RowParity::from(y - stub[Axis2::Y])),
                         Box::new(value.cloned().unwrap_or_default()),
@@ -218,11 +215,11 @@ impl PivotTable {
         // are not in the corner.
         if self.metadata.corner_text.is_some()
             && self.style.look.row_label_position == LabelPosition::Nested
-            && stub.x() > 0
-            && stub.y() > 0
+            && stub.0 > 0
+            && stub.0 > 0
         {
             body.put(
-                IndexRect2::new(0..stub.x(), 0..stub.y()),
+                CellRect::new(0..stub.0, 0..stub.1),
                 CellInner::new(
                     Area::Corner,
                     self.metadata.corner_text.clone().unwrap_or_default(),
@@ -230,22 +227,14 @@ impl PivotTable {
             );
         }
 
-        if body.n.x() > 0 && body.n.y() > 0 {
-            body.h_line(Border::InnerFrame(BoxBorder::Top), 0..body.n.x(), 0);
-            body.h_line(
-                Border::InnerFrame(BoxBorder::Bottom),
-                0..body.n.x(),
-                body.n.y(),
-            );
-            body.v_line(Border::InnerFrame(BoxBorder::Left), 0, 0..body.n.y());
-            body.v_line(
-                Border::InnerFrame(BoxBorder::Right),
-                body.n.x(),
-                0..body.n.y(),
-            );
+        if body.n.0 > 0 && body.n.1 > 0 {
+            body.h_line(Border::InnerFrame(BoxBorder::Top), 0..body.n.0, 0);
+            body.h_line(Border::InnerFrame(BoxBorder::Bottom), 0..body.n.0, body.n.1);
+            body.v_line(Border::InnerFrame(BoxBorder::Left), 0, 0..body.n.1);
+            body.v_line(Border::InnerFrame(BoxBorder::Right), body.n.0, 0..body.n.1);
 
-            body.h_line(Border::DataTop, 0..body.n.x(), stub.y());
-            body.v_line(Border::DataLeft, stub.x(), 0..body.n.y());
+            body.h_line(Border::DataTop, 0..body.n.0, stub.1);
+            body.v_line(Border::DataLeft, stub.0, 0..body.n.1);
         }
         body
     }
@@ -466,7 +455,7 @@ impl<'a> Heading<'a> {
                 let rotate =
                     (rotate_inner_labels && is_inner_row) || (rotate_outer_labels && is_outer_row);
                 table.put(
-                    IndexRect2::for_ranges((h, x1 + h_ofs..x2 + h_ofs), y1..y2),
+                    CellRect::for_ranges((h, x1 + h_ofs..x2 + h_ofs), y1..y2),
                     CellInner::new(Area::Labels(h), Box::new(name.clone())).with_rotate(rotate),
                 );
 
@@ -546,7 +535,7 @@ impl<'a> Heading<'a> {
 
         if dimension_label_position == LabelPosition::Corner {
             table.put(
-                IndexRect2::new(v_ofs..v_ofs + 1, 0..h_ofs),
+                CellRect::new(v_ofs..v_ofs + 1, 0..h_ofs),
                 CellInner::new(Area::Corner, self.dimension.root.name.clone()),
             );
         }
index f96b44e34b23337aeace5761fd6cd260606448b2..079783b25cc0bf493739efbbe5232daa64091cea 100644 (file)
@@ -25,8 +25,8 @@ use itertools::interleave;
 use num::Integer;
 use smallvec::SmallVec;
 
-use crate::output::pivot::{IndexRect2, VertAlign};
-use crate::output::table::{DrawCell, CellPos};
+use crate::output::pivot::VertAlign;
+use crate::output::table::{CellPos, CellRect, DrawCell};
 
 use super::pivot::{Axis2, BorderStyle, Coord2, Look, PivotTable, Rect2, Stroke};
 use super::table::{Content, Table};
@@ -193,7 +193,7 @@ struct Page {
     h: CellPos,
 
     /// Main region of cells to render.
-    r: IndexRect2,
+    r: CellRect,
 
     /// Mappings from [Page] positions to those in the underlying [Table].
     maps: EnumMap<Axis2, [Map; 2]>,
@@ -354,7 +354,7 @@ fn is_rule(z: usize) -> bool {
 
 #[derive(Clone)]
 pub struct RenderCell<'a> {
-    rect: IndexRect2,
+    rect: CellRect,
     content: &'a Content,
 }
 
@@ -391,7 +391,7 @@ impl Page {
 
         // Calculate minimum and maximum widths of cells that do not span
         // multiple columns.
-        let mut unspanned_columns = EnumMap::from_fn(|_| vec![0; n.x()]);
+        let mut unspanned_columns = EnumMap::from_fn(|_| vec![0; n.0]);
         for cell in table.cells().filter(|cell| cell.col_span() == 1) {
             let mut w = device.measure_cell_width(&DrawCell::new(cell.inner(), &table));
             if device.params().px_size.is_some() {
@@ -448,7 +448,7 @@ impl Page {
         // In pathological cases, spans can cause the minimum width of a column
         // to exceed the maximum width.  This bollixes our interpolation
         // algorithm later, so fix it up.
-        for i in 0..n.x() {
+        for i in 0..n.0 {
             if columns[Min][i] > columns[Max][i] {
                 columns[Max][i] = columns[Min][i];
             }
@@ -483,7 +483,7 @@ impl Page {
             let w = joined_width(&cp_x, rect[X].clone());
             let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &table), w);
 
-            let row = &mut unspanned_rows[cell.pos.y()];
+            let row = &mut unspanned_rows[cell.pos.1];
             if h > *row {
                 *row = h;
             }
@@ -519,7 +519,7 @@ impl Page {
                 h[axis] = 0;
             }
         }
-        let r = IndexRect2::new(h[X]..n[X], h[Y]..n[Y]);
+        let r = CellRect::new(h[X]..n[X], h[Y]..n[Y]);
         let maps = Self::new_mappings(h, &r);
         Self {
             table,
@@ -620,7 +620,7 @@ impl Page {
         *self.cp[axis].last().unwrap()
     }
 
-    fn new_mappings(h: CellPos, r: &IndexRect2) -> EnumMap<Axis2, [Map; 2]> {
+    fn new_mappings(h: CellPos, r: &CellRect) -> EnumMap<Axis2, [Map; 2]> {
         EnumMap::from_fn(|axis| {
             [
                 Map {
@@ -659,7 +659,7 @@ impl Page {
         let maps = EnumMap::from_fn(|axis| self.get_map(axis, coord[axis]));
         let cell = self.table.get(self.map_coord(coord));
         RenderCell {
-            rect: IndexRect2(cell.rect().0.map(|axis, Range { start, end }| {
+            rect: CellRect(cell.rect().0.map(|axis, Range { start, end }| {
                 let m = maps[axis];
                 max(m.p0, start - m.ofs)..min(m.p0 + m.n, end - m.ofs)
             })),
@@ -839,17 +839,17 @@ impl Page {
         self.draw_cells(
             device,
             ofs,
-            IndexRect2::new(0..self.n[X] * 2 + 1, 0..self.n[Y] * 2 + 1),
+            CellRect::new(0..self.n[X] * 2 + 1, 0..self.n[Y] * 2 + 1),
         );
     }
 
-    fn draw_cells(&self, device: &mut dyn Device, ofs: Coord2, cells: IndexRect2) {
+    fn draw_cells(&self, device: &mut dyn Device, ofs: Coord2, cells: CellRect) {
         use Axis2::*;
         for y in cells[Y].clone() {
             let mut x = cells[X].start;
             while x < cells[X].end {
                 if !is_rule(x) && !is_rule(y) {
-                    let cell = self.get_cell(CellPos::new(x / 2, y / 2));
+                    let cell = self.get_cell(CellPos(x / 2, y / 2));
                     self.draw_cell(device, ofs, &cell);
                     x = rule_ofs(cell.rect[X].end);
                 } else {
@@ -861,7 +861,7 @@ impl Page {
         for y in cells[Y].clone() {
             for x in cells[X].clone() {
                 if is_rule(x) || is_rule(y) {
-                    self.draw_rule(device, ofs, CellPos::new(x, y));
+                    self.draw_rule(device, ofs, CellPos(x, y));
                 }
             }
         }
@@ -1282,7 +1282,7 @@ impl Break {
             if self.axis == Axis2::Y && device.params().can_adjust_break {
                 let mut x = 0;
                 while x < self.page.n[Axis2::X] {
-                    let cell = self.page.get_cell(CellPos::new(x, z));
+                    let cell = self.page.get_cell(CellPos(x, z));
                     let better_pixel = device.adjust_break(
                         cell.content,
                         Coord2::new(
index 3413c166052b48e54955be2da645178f278b1ac2..4626addb5becea0f3a341ca145823bf7c2e86771 100644 (file)
@@ -36,7 +36,7 @@ use enum_map::{EnumMap, enum_map};
 use ndarray::{Array, Array2};
 
 use crate::output::{
-    pivot::{CellStyle, DisplayValue, FontStyle, Footnote, HorzAlign, IndexRect2, ValueInner},
+    pivot::{CellStyle, DisplayValue, FontStyle, Footnote, HorzAlign, ValueInner},
     spv::html,
 };
 
@@ -46,47 +46,26 @@ use super::pivot::{
 
 /// The `(x,y)` position of a cell in a [Table].
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
-pub struct CellPos(pub EnumMap<Axis2, usize>);
+pub struct CellPos(
+    /// X
+    pub usize,
+    /// Y
+    pub usize,
+);
 
 impl CellPos {
-    pub fn new(x: usize, y: usize) -> Self {
-        use Axis2::*;
-        Self(enum_map! {
-            X => x,
-            Y => y
-        })
-    }
-
     pub fn for_axis((a, az): (Axis2, usize), bz: usize) -> Self {
-        let mut coord = Self::default();
-        coord[a] = az;
-        coord[!a] = bz;
-        coord
+        match a {
+            Axis2::X => Self(az, bz),
+            Axis2::Y => Self(bz, az),
+        }
     }
 
-    pub fn from_fn<F>(f: F) -> Self
+    pub fn from_fn<F>(mut f: F) -> Self
     where
         F: FnMut(Axis2) -> usize,
     {
-        Self(EnumMap::from_fn(f))
-    }
-
-    pub fn x(&self) -> usize {
-        self.0[Axis2::X]
-    }
-
-    pub fn y(&self) -> usize {
-        self.0[Axis2::Y]
-    }
-
-    pub fn get(&self, axis: Axis2) -> usize {
-        self.0[axis]
-    }
-}
-
-impl From<EnumMap<Axis2, usize>> for CellPos {
-    fn from(value: EnumMap<Axis2, usize>) -> Self {
-        Self(value)
+        Self(f(Axis2::X), f(Axis2::Y))
     }
 }
 
@@ -94,13 +73,52 @@ impl Index<Axis2> for CellPos {
     type Output = usize;
 
     fn index(&self, index: Axis2) -> &Self::Output {
-        &self.0[index]
+        match index {
+            Axis2::X => &self.0,
+            Axis2::Y => &self.1,
+        }
     }
 }
 
 impl IndexMut<Axis2> for CellPos {
     fn index_mut(&mut self, index: Axis2) -> &mut Self::Output {
-        &mut self.0[index]
+        match index {
+            Axis2::X => &mut self.0,
+            Axis2::Y => &mut self.1,
+        }
+    }
+}
+
+/// A rectangular group of cells in a [Table].
+#[derive(Clone, Debug, Default)]
+pub struct CellRect(
+    /// The `x` range and `y` range spanned by the rectangle.
+    pub EnumMap<Axis2, Range<usize>>,
+);
+
+impl CellRect {
+    pub fn new(x_range: Range<usize>, y_range: Range<usize>) -> Self {
+        Self(enum_map! {
+            Axis2::X => x_range.clone(),
+            Axis2::Y => y_range.clone(),
+        })
+    }
+    pub fn for_cell(cell: CellPos) -> Self {
+        Self::new(cell.0..cell.0 + 1, cell.1..cell.1 + 1)
+    }
+    pub fn for_ranges((a, a_range): (Axis2, Range<usize>), b_range: Range<usize>) -> Self {
+        let b = !a;
+        let mut ranges = EnumMap::default();
+        ranges[a] = a_range;
+        ranges[b] = b_range;
+        Self(ranges)
+    }
+    pub fn top_left(&self) -> CellPos {
+        use Axis2::*;
+        CellPos(self[X].start, self[Y].start)
+    }
+    pub fn is_empty(&self) -> bool {
+        self[Axis2::X].is_empty() || self[Axis2::Y].is_empty()
     }
 }
 
@@ -119,12 +137,12 @@ impl CellRef<'_> {
         self.content.is_empty()
     }
 
-    pub fn rect(&self) -> IndexRect2 {
+    pub fn rect(&self) -> CellRect {
         self.content.rect(self.pos)
     }
 
     pub fn next_x(&self) -> usize {
-        self.content.next_x(self.pos.x())
+        self.content.next_x(self.pos.0)
     }
 
     pub fn is_top_left(&self) -> bool {
@@ -163,7 +181,7 @@ impl Content {
     /// Returns the rectangle that this cell covers, only if the cell contains
     /// that information. (Joined cells always do, and other cells usually
     /// don't.)
-    pub fn joined_rect(&self) -> Option<&IndexRect2> {
+    pub fn joined_rect(&self) -> Option<&CellRect> {
         match self {
             Content::Join(cell) => Some(&cell.region),
             _ => None,
@@ -172,10 +190,10 @@ impl Content {
 
     /// Returns the rectangle that this cell covers. If the cell doesn't contain
     /// that information, returns a rectangle containing `pos`.
-    pub fn rect(&self, pos: CellPos) -> IndexRect2 {
+    pub fn rect(&self, pos: CellPos) -> CellRect {
         match self {
             Content::Join(cell) => cell.region.clone(),
-            _ => IndexRect2::for_cell(pos),
+            _ => CellRect::for_cell(pos),
         }
     }
 
@@ -214,11 +232,11 @@ pub struct Cell {
     inner: CellInner,
 
     /// Occupied table region.
-    region: IndexRect2,
+    region: CellRect,
 }
 
 impl Cell {
-    fn new(inner: CellInner, region: IndexRect2) -> Self {
+    fn new(inner: CellInner, region: CellRect) -> Self {
         Self { inner, region }
     }
 }
@@ -290,12 +308,12 @@ impl Table {
         Self {
             n,
             h: headers,
-            contents: Array::default((n.x(), n.y())),
+            contents: Array::default((n.0, n.1)),
             areas,
             borders,
             rules: enum_map! {
-                Axis2::X => Array::default((n.x() + 1, n.y())),
-                Axis2::Y => Array::default((n.x(), n.y() + 1)),
+                Axis2::X => Array::default((n.0 + 1, n.1)),
+                Axis2::Y => Array::default((n.0, n.1 + 1)),
             },
             value_options,
         }
@@ -304,15 +322,15 @@ impl Table {
     pub fn get(&self, coord: CellPos) -> CellRef<'_> {
         CellRef {
             pos: coord,
-            content: &self.contents[[coord.x(), coord.y()]],
+            content: &self.contents[[coord.0, coord.1]],
         }
     }
 
     pub fn get_rule(&self, axis: Axis2, pos: CellPos) -> BorderStyle {
-        self.rules[axis][[pos.x(), pos.y()]].map_or(BorderStyle::none(), |b| self.borders[b])
+        self.rules[axis][[pos.0, pos.1]].map_or(BorderStyle::none(), |b| self.borders[b])
     }
 
-    pub fn put(&mut self, region: IndexRect2, inner: CellInner) {
+    pub fn put(&mut self, region: CellRect, inner: CellInner) {
         use Axis2::*;
         if region[X].len() == 1 && region[Y].len() == 1 {
             self.contents[[region[X].start, region[Y].start]] = Content::Value(inner);
@@ -360,9 +378,9 @@ impl Table {
 
     /// The heading region that `pos` is part of, if any.
     pub fn heading_region(&self, pos: CellPos) -> Option<HeadingRegion> {
-        if pos.x() < self.h.x() {
+        if pos.0 < self.h.0 {
             Some(HeadingRegion::Rows)
-        } else if pos.y() < self.h.y() {
+        } else if pos.1 < self.h.1 {
             Some(HeadingRegion::Columns)
         } else {
             None
@@ -394,8 +412,8 @@ impl Iterator for XIter<'_> {
     fn next(&mut self) -> Option<Self::Item> {
         let next_x = self
             .x
-            .map_or(0, |x| self.table.get(CellPos::new(x, self.y)).next_x());
-        if next_x >= self.table.n.x() {
+            .map_or(0, |x| self.table.get(CellPos(x, self.y)).next_x());
+        if next_x >= self.table.n.0 {
             None
         } else {
             self.x = Some(next_x);
@@ -417,7 +435,7 @@ impl<'a> Cells<'a> {
             next: if table.is_empty() {
                 None
             } else {
-                Some(table.get(CellPos::new(0, 0)))
+                Some(table.get(CellPos(0, 0)))
             },
         }
     }
@@ -434,9 +452,9 @@ impl<'a> Iterator for Cells<'a> {
         self.next = loop {
             let next_x = next.next_x();
             let coord = if next_x < self.table.n[X] {
-                CellPos::new(next_x, next.pos.y())
-            } else if next.pos.y() + 1 < self.table.n[Y] {
-                CellPos::new(0, next.pos.y() + 1)
+                CellPos(next_x, next.pos.1)
+            } else if next.pos.1 + 1 < self.table.n[Y] {
+                CellPos(0, next.pos.1 + 1)
             } else {
                 break None;
             };
index d53a8c29a1206a62150847d7ffd7b786a663a92b..5bb412c311b2ba8f9683ee31c19043887885bd41 100644 (file)
@@ -21,7 +21,7 @@ use enum_map::EnumMap;
 use serde::Serialize;
 
 use crate::{
-    format::{Format, Settings as FormatSettings, F8_2},
+    format::{F8_2, Format, Settings as FormatSettings},
     message::Severity,
     output::pivot::Look,
 };