cleanup
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 3 Jan 2026 19:36:37 +0000 (11:36 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 3 Jan 2026 19:36:37 +0000 (11:36 -0800)
rust/pspp/src/cli/show_spv.rs
rust/pspp/src/spv/read/legacy_bin.rs
rust/pspp/src/spv/read/legacy_xml.rs

index a62c18e7a62e685dc1f2e6bccc127540d60bd874..95a87bff65a4b5400e72d31019c8dfd5e2a0c26b 100644 (file)
@@ -24,8 +24,12 @@ use pspp::{
     },
     spv::{
         SpvArchive,
-        legacy_bin::{DataValue, LegacyBin},
-        read::{ReadSeek, legacy_xml::Visualization, structure::OutlineItem},
+        legacy_bin::LegacyBin,
+        read::{
+            ReadSeek,
+            legacy_xml::{DataValue, Visualization},
+            structure::OutlineItem,
+        },
     },
 };
 use std::{
index ed690c2499510f7ad38f39594a894f1872ffa79c..aa67d75402bbc591512e2dbd895cf20628776ded 100644 (file)
@@ -1,20 +1,14 @@
 //! Legacy binary data.
-use std::{
-    collections::HashMap,
-    io::{Read, Seek, SeekFrom},
-};
+use std::io::{Read, Seek, SeekFrom};
 
 use binrw::{BinRead, BinResult, binread};
-use chrono::{NaiveDateTime, NaiveTime};
 use displaydoc::Display;
 use encoding_rs::UTF_8;
 use indexmap::IndexMap;
 
 use crate::{
     data::Datum,
-    format::{Category, Format},
-    output::pivot::value::Value,
-    spv::read::light::{U32String, decode_format, parse_vec},
+    spv::read::light::{U32String, parse_vec},
 };
 
 /// A warning decoding a legacy binary member.
@@ -142,72 +136,6 @@ impl LegacyBin {
     }
 }
 
-/// One data value.
-#[derive(Clone, Debug)]
-pub struct DataValue {
-    /// Optional index.
-    ///
-    /// This is always `None` as initially decoded.
-    pub index: Option<f64>,
-
-    /// Data value.
-    pub value: Datum<String>,
-}
-
-impl DataValue {
-    /// Category index, if any.  This is the numeric value of the datum, if
-    /// there is one, falling back to the index.
-    pub fn category(&self) -> Option<usize> {
-        match &self.value {
-            Datum::Number(number) => *number,
-            _ if self.index.is_some() => self.index,
-            Datum::String(string) => {
-                // This only comes up in a few cases which indicate something
-                // odd might have happened to the table in the SPV files.
-                string.parse().ok()
-            }
-        }
-        .and_then(|v| (v >= 0.0 && v < usize::MAX as f64).then_some(v as usize))
-    }
-
-    /// Interprets this data value as a [Format], first by looking it up in
-    /// `format_map` and otherwise by interpreting it as a [Format] directly.
-    ///
-    /// This should probably be a method on some hypothetical FormatMap.
-    pub fn as_format(&self, format_map: &HashMap<i64, Format>) -> Format {
-        let f = match &self.value {
-            Datum::Number(Some(number)) => *number as i64,
-            Datum::Number(None) => 0,
-            Datum::String(s) => s.parse().unwrap_or_default(),
-        };
-        match format_map.get(&f) {
-            Some(format) => *format,
-            None => decode_format(f as u32, &mut |_| () /*XXX*/),
-        }
-    }
-
-    /// Returns this data value interpreted using `format`.
-    pub fn as_pivot_value(&self, format: Format) -> Value {
-        if format.type_().category() == Category::Date
-            && let Some(s) = self.value.as_string()
-            && let Ok(date_time) =
-                NaiveDateTime::parse_from_str(s.as_str(), "%Y-%m-%dT%H:%M:%S%.3f")
-        {
-            Value::new_date(date_time)
-        } else if format.type_().category() == Category::Time
-            && let Some(s) = self.value.as_string()
-            && let Ok(time) = NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S%.3f")
-        {
-            Value::new_time(time)
-        } else if !self.value.is_sysmis() {
-            Value::new_datum(&self.value)
-        } else {
-            Value::new_empty()
-        }
-        .with_format(format)
-    }
-}
-
 #[binread]
 #[br(little)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
index 93202ca2c510a4f046baeaee700a57008c15e85f..e4c575a090f3e226db71a77b3dc511e9c7bb3639 100644 (file)
@@ -41,9 +41,78 @@ use crate::{
         look::{self, Area, AreaStyle, CellStyle, Color, HorzAlign, Look, RowParity, VertAlign},
         value::Value,
     },
-    spv::read::legacy_bin::DataValue,
+    spv::read::light::decode_format,
 };
 
+/// One data value.
+#[derive(Clone, Debug)]
+pub struct DataValue {
+    /// Optional index.
+    ///
+    /// This is always `None` as initially decoded.
+    pub index: Option<f64>,
+
+    /// Data value.
+    pub value: Datum<String>,
+}
+
+impl DataValue {
+    /// Category index, if any.  This is the numeric value of the datum, if
+    /// there is one, falling back to the index.
+    pub fn category(&self) -> Option<usize> {
+        match &self.value {
+            Datum::Number(number) => *number,
+            _ if self.index.is_some() => self.index,
+            Datum::String(string) => {
+                // This only comes up in a few cases which indicate something
+                // odd might have happened to the table in the SPV files.
+                string.parse().ok()
+            }
+        }
+        .and_then(|v| (v >= 0.0 && v < usize::MAX as f64).then_some(v as usize))
+    }
+
+    /// Interprets this data value as a [Format], first by looking it up in
+    /// `format_map` and otherwise by interpreting it as a [Format] directly.
+    ///
+    /// This should probably be a method on some hypothetical FormatMap.
+    pub fn as_format(
+        &self,
+        format_map: &HashMap<i64, crate::format::Format>,
+    ) -> crate::format::Format {
+        let f = match &self.value {
+            Datum::Number(Some(number)) => *number as i64,
+            Datum::Number(None) => 0,
+            Datum::String(s) => s.parse().unwrap_or_default(),
+        };
+        match format_map.get(&f) {
+            Some(format) => *format,
+            None => decode_format(f as u32, &mut |_| () /*XXX*/),
+        }
+    }
+
+    /// Returns this data value interpreted using `format`.
+    pub fn as_pivot_value(&self, format: crate::format::Format) -> Value {
+        if format.type_().category() == crate::format::Category::Date
+            && let Some(s) = self.value.as_string()
+            && let Ok(date_time) =
+                NaiveDateTime::parse_from_str(s.as_str(), "%Y-%m-%dT%H:%M:%S%.3f")
+        {
+            Value::new_date(date_time)
+        } else if format.type_().category() == crate::format::Category::Time
+            && let Some(s) = self.value.as_string()
+            && let Ok(time) = NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S%.3f")
+        {
+            Value::new_time(time)
+        } else if !self.value.is_sysmis() {
+            Value::new_datum(&self.value)
+        } else {
+            Value::new_empty()
+        }
+        .with_format(format)
+    }
+}
+
 #[derive(Debug)]
 struct Ref<T> {
     references: String,