]> pintos-os.org Git - pspp/commitdiff
better types
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 20 Aug 2026 00:39:41 +0000 (17:39 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 20 Aug 2026 00:39:41 +0000 (17:39 -0700)
rust/pspp/src/spv/read/graph.rs

index 45a12e0930ee0b0a30da22377adf7d754b7000e9..2d4d959c1d7189a53379414b8ff9f0d51b7f0aad 100644 (file)
@@ -29,6 +29,7 @@ use std::{
 };
 
 use cairo::{Context, RecordingSurface};
+use enum_iterator::all;
 use enum_map::{Enum, EnumMap, enum_map};
 use indexmap::{IndexMap, IndexSet};
 use itertools::Itertools;
@@ -376,9 +377,9 @@ impl Visualization {
             .iter()
             .map(|raw| Element::new(raw, locale, series, bin_widths, axis_domains, styles))
             .collect::<Result<Vec<_>, _>>()?;
-        let dimensions = graph.coordinates.dimensions().collect_vec();
-        for (index, axis) in [Axis3::X, Axis3::Y, Axis3::Z].into_iter().enumerate() {
-            let mut domain = if let Some(dimension) = dimensions.get(index)
+        let dimensions = &graph.coordinates.dimensions;
+        for axis in all() {
+            let mut domain = if let Some(dimension) = &dimensions[axis]
                 && let Some(domain_name) = &dimension.domain
                 && let Some(domain) = domains.get(domain_name.as_str())
             {
@@ -447,7 +448,7 @@ impl Visualization {
                 {
                     *max = Some(0.0);
                 }
-                if let Some(dimension) = dimensions.get(index) {
+                if let Some(dimension) = &dimensions[axis] {
                     let mmin = min.unwrap();
                     let mmax = max.unwrap();
                     let range = mmax - mmin;
@@ -460,8 +461,8 @@ impl Visualization {
                 }
             }
 
-            let axis2 = dimensions
-                .get(index)
+            let axis2 = dimensions[axis]
+                .as_ref()
                 .and_then(|dimension| dimension.axis.first());
             axis_domains[axis] = AxisDomain {
                 domain,
@@ -647,7 +648,7 @@ impl Visualization {
                     &faceting[axis],
                     &axis_domains[axis.into()],
                     rect.0[axis].length() - heading_heights[!axis],
-                    graph.axis_dimension(axis),
+                    graph.axis_dimension(axis.into()),
                     &font_metrics,
                     axis == Axis2::Y,
                 );
@@ -2792,18 +2793,15 @@ impl Graph {
     }
 
     fn x_dimension(&self) -> Option<&Dimension> {
-        self.coordinates.dimensions().next()
+        self.axis_dimension(Axis3::X)
     }
 
     fn y_dimension(&self) -> Option<&Dimension> {
-        self.coordinates.dimensions().skip(1).next()
+        self.axis_dimension(Axis3::Y)
     }
 
-    fn axis_dimension(&self, axis: Axis2) -> Option<&Dimension> {
-        match axis {
-            Axis2::X => self.x_dimension(),
-            Axis2::Y => self.y_dimension(),
-        }
+    fn axis_dimension(&self, axis: Axis3) -> Option<&Dimension> {
+        self.coordinates.dimensions[axis].as_ref()
     }
 }
 
@@ -3553,31 +3551,43 @@ struct SetFrameStyle {
     style: String,
 }
 
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
+#[derive(Debug)]
 struct Coordinates {
-    #[serde(rename = "$value")]
-    #[serde(default)]
-    children: Vec<CoordinatesChild>,
+    dimensions: EnumMap<Axis3, Option<Dimension>>,
 }
 
-impl Coordinates {
-    fn dimensions(&self) -> impl Iterator<Item = &Dimension> {
-        self.children.iter().filter_map(|child| match child {
+impl<'de> Deserialize<'de> for Coordinates {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        #[derive(Deserialize, Debug)]
+        #[serde(rename_all = "camelCase")]
+        struct RawCoordinates {
+            #[serde(rename = "$value")]
+            #[serde(default)]
+            children: Vec<CoordinatesChild>,
+        }
+
+        #[derive(Deserialize, Debug)]
+        #[serde(rename_all = "camelCase")]
+        enum CoordinatesChild {
+            Dimension(Dimension),
+            #[serde(other)]
+            Other,
+        }
+
+        let raw = RawCoordinates::deserialize(deserializer)?;
+        let mut dimensions = raw.children.into_iter().filter_map(|child| match child {
             CoordinatesChild::Dimension(dimension) => Some(dimension),
             CoordinatesChild::Other => None,
-        })
+        });
+        let dimensions =
+            EnumMap::from_array([dimensions.next(), dimensions.next(), dimensions.next()]);
+        Ok(Self { dimensions })
     }
 }
 
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase")]
-enum CoordinatesChild {
-    Dimension(Dimension),
-    #[serde(other)]
-    Other,
-}
-
 #[derive(Deserialize, Debug)]
 #[serde(rename_all = "camelCase")]
 struct Dimension {