work (fails tests)
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 7 Jan 2026 16:16:47 +0000 (08:16 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 7 Jan 2026 16:16:47 +0000 (08:16 -0800)
rust/pspp/src/spv/read/light.rs

index a3fe4b6ed7725fdd7bb78f7087c87fb110a07200..3c0851a4fd03598ebe3ffee9ad1cbfcf37b6f837 100644 (file)
@@ -1,6 +1,7 @@
 use std::{
     fmt::Debug,
     io::{Read, Seek},
+    iter::{repeat, zip},
     ops::Deref,
     str::FromStr,
     sync::Arc,
@@ -202,17 +203,14 @@ impl LightTable {
                 dimension
             })
             .collect::<Vec<_>>();
-        let dimensions = match self.axes.decode(dimensions) {
-            Ok(dimensions) => dimensions,
-            Err((warning, dimensions)) => {
+        let axes = self
+            .axes
+            .decode(dimensions.len())
+            .unwrap_or_else(|warning| {
                 warn(warning);
-                dimensions
-                    .into_iter()
-                    .map(|dimension| (Axis3::Y, dimension))
-                    .collect()
-            }
-        };
-        let pivot_table = PivotTable::new(dimensions)
+                vec![Axis3::Y; dimensions.len()]
+            });
+        let pivot_table = PivotTable::new(zip(axes, dimensions))
             .with_style(PivotTableStyle {
                 look: Arc::new(self.decode_look(encoding)),
                 rotate_inner_column_labels: self.header.rotate_inner_column_labels,
@@ -1755,56 +1753,36 @@ struct Axes {
 }
 
 impl Axes {
-    fn decode(
-        &self,
-        dimensions: Vec<pivot::Dimension>,
-    ) -> Result<Vec<(Axis3, pivot::Dimension)>, (LightWarning, Vec<pivot::Dimension>)> {
-        let n = self.layers.len() + self.rows.len() + self.columns.len();
-        if n != dimensions.len() {
-            return Err((
-                LightWarning::WrongAxisCount {
-                    expected: dimensions.len(),
-                    actual: n,
-                    n_layers: self.layers.len(),
-                    n_rows: self.rows.len(),
-                    n_columns: self.columns.len(),
-                },
-                dimensions,
-            ));
+    fn decode(&self, n: usize) -> Result<Vec<Axis3>, LightWarning> {
+        let actual = self.layers.len() + self.rows.len() + self.columns.len();
+        if actual != n {
+            return Err(LightWarning::WrongAxisCount {
+                expected: n,
+                actual,
+                n_layers: self.layers.len(),
+                n_rows: self.rows.len(),
+                n_columns: self.columns.len(),
+            });
         }
 
+        let mut axes = vec![None; n];
+
         fn axis_dims(axis: Axis3, dimensions: &[u32]) -> impl Iterator<Item = (Axis3, usize)> {
-            dimensions.iter().map(move |d| (axis, *d as usize))
+            repeat(axis).zip(dimensions.iter().copied().map(|x| x.try_into().unwrap()))
         }
 
-        let mut dimensions = dimensions.into_iter().map(Some).collect::<Vec<_>>();
-        let mut output = Vec::with_capacity(n);
-
         for (axis, index) in axis_dims(Axis3::Z, &self.layers)
             .chain(axis_dims(Axis3::Y, &self.rows))
             .chain(axis_dims(Axis3::X, &self.columns))
         {
-            let result = dimensions
-                .get_mut(index)
-                .ok_or(LightWarning::InvalidDimensionIndex { index, n })
-                .and_then(|dimension| {
-                    dimension
-                        .take()
-                        .ok_or(LightWarning::DuplicateDimensionIndex(index))
-                });
-            match result {
-                Ok(dimension) => output.push((axis, dimension)),
-                Err(error) => {
-                    let dimensions = dimensions
-                        .into_iter()
-                        .flatten()
-                        .chain(output.into_iter().map(|(_axis, dimension)| dimension))
-                        .collect();
-                    return Err((error, dimensions));
-                }
+            match axes.get_mut(index) {
+                None => return Err(LightWarning::InvalidDimensionIndex { index, n }),
+                Some(Some(_)) => return Err(LightWarning::DuplicateDimensionIndex(index)),
+                Some(inner) => *inner = Some(axis),
             }
         }
-        Ok(output)
+
+        Ok(axes.into_iter().flatten().collect())
     }
 }