cleanup
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 3 Jan 2026 18:57:22 +0000 (10:57 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 3 Jan 2026 18:57:22 +0000 (10:57 -0800)
rust/pspp/src/spv/read/legacy_xml.rs

index 59331d3a7647031e8d6fbae68d9b52caceea1764..5088fa8ad06c1bf1c99dc471e01b94d219552362 100644 (file)
@@ -76,6 +76,36 @@ impl Map {
         Self::default()
     }
 
+    fn from_format(format: &Format) -> (Self, crate::format::Format) {
+        let f = format.decode();
+        let mut map = Self::new();
+        for relabel in &format.relabels {
+            let value = match relabel.to.trim().parse::<f64>().ok() {
+                Some(to) if format.try_strings_as_numbers => Datum::Number(Some(to)),
+                Some(to) => Datum::String(
+                    Datum::<String>::Number(Some(to))
+                        .display(f)
+                        .with_stretch()
+                        .to_string(),
+                ),
+                None => Datum::String(relabel.to.clone()),
+            };
+            map.0.insert(OrderedFloat(relabel.from), value);
+        }
+        (map, f)
+    }
+
+    fn from_string_format(string_format: &StringFormat) -> Self {
+        let mut map = Self::new();
+        for relabel in &string_format.relabels {
+            map.0.insert(
+                OrderedFloat(relabel.from),
+                Datum::String(relabel.to.clone()),
+            );
+        }
+        map
+    }
+
     fn remap_formats(
         &mut self,
         format: &Option<Format>,
@@ -85,7 +115,7 @@ impl Map {
             (
                 Some(format.decode()),
                 format.relabels.as_slice(),
-                format.try_strings_as_numbers.unwrap_or_default(),
+                format.try_strings_as_numbers,
             )
         } else if let Some(string_format) = &string_format {
             (None, string_format.relabels.as_slice(), false)
@@ -141,7 +171,8 @@ impl Map {
         }
     }
 
-    fn remap_vmes(&mut self, value_map: &[ValueMapEntry]) {
+    fn from_vmes(value_map: &[ValueMapEntry]) -> Self {
+        let mut map = Map::new();
         for vme in value_map {
             for from in vme.from.split(';') {
                 if let Ok(from) = from.trim().parse::<f64>() {
@@ -150,10 +181,11 @@ impl Map {
                     } else {
                         Datum::String(vme.to.clone())
                     };
-                    self.0.insert(OrderedFloat(from), to);
+                    map.0.insert(OrderedFloat(from), to);
                 }
             }
         }
+        map
     }
 
     fn lookup<'a>(&'a self, dv: &'a DataValue) -> &'a Datum<String> {
@@ -868,13 +900,22 @@ impl SourceVariable {
         } else {
             Vec::new()
         };
-        let mut map = Map::new();
-        let format = map.remap_formats(&self.format, &self.string_format);
+        let mut map = if let Some(format) = &self.format {
+            Map::from_format(format).0
+        } else if let Some(string_format) = &self.string_format {
+            Map::from_string_format(string_format)
+        } else {
+            Map::new()
+        };
         if !map.0.is_empty() {
             map.apply(&mut data);
             map = Map::new();
         } else if let Some(label_series) = label_series {
-            map.insert_labels(&data, label_series, format);
+            map.insert_labels(
+                &data,
+                label_series,
+                self.format.as_ref().map_or(F8_0, |f| f.decode()),
+            );
         }
         series.insert(
             &self.id,
@@ -953,8 +994,7 @@ impl DerivedVariable {
             });
             vec![]
         };
-        let mut map = Map::new();
-        map.remap_vmes(&self.value_map);
+        let mut map = Map::from_vmes(&self.value_map);
         map.apply(&mut values);
         map.remap_formats(&self.format, &self.string_format);
         if values
@@ -1017,8 +1057,8 @@ struct Format {
     prefix: String,
     #[serde(default, rename = "@suffix")]
     suffix: String,
-    #[serde(rename = "@tryStringsAsNumbers")]
-    try_strings_as_numbers: Option<bool>,
+    #[serde(rename = "@tryStringsAsNumbers", default)]
+    try_strings_as_numbers: bool,
     #[serde(default, rename = "relabel")]
     relabels: Vec<Relabel>,
     #[serde(default, rename = "affix")]