more cleanup
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Jul 2025 15:37:55 +0000 (08:37 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Jul 2025 15:37:55 +0000 (08:37 -0700)
rust/pspp/src/data.rs
rust/pspp/src/main.rs
rust/pspp/src/sys/raw.rs
rust/pspp/src/sys/test.rs

index 9334eaf668bedbea96258e132d4f031581c5cf19..59026039960205e4a28b80d156d866867e1d1eaf 100644 (file)
@@ -401,3 +401,13 @@ impl From<&[u8]> for Datum {
         Self::String(value.into())
     }
 }
+
+/// A case in a data set.
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Case(
+    /// One [Datum] per variable in the corresponding [Dictionary], in the same
+    /// order.
+    ///
+    /// [Dictionary]: crate::dictionary::Dictionary
+    pub Vec<Datum>,
+);
index 50eaa8adf1c6a770707f7f27aab5ccb903893cc7..f14b44570c7eba0158ca30d46b07972d1b6896b7 100644 (file)
@@ -106,7 +106,7 @@ impl Convert {
         }
 
         for (_case_number, case) in (0..self.max_cases.unwrap_or(u64::MAX)).zip(cases) {
-            output.write_record(case?.into_iter().zip(dictionary.variables.iter()).map(
+            output.write_record(case?.0.into_iter().zip(dictionary.variables.iter()).map(
                 |(datum, variable)| {
                     datum
                         .display(variable.print_format, variable.encoding)
index b1263be32c530393bd571487e0ac01190bccea2e..d9de5c23041c2979efac5b585010c555f052fc25 100644 (file)
@@ -20,7 +20,7 @@
 //! raw details.  Most readers will want to use higher-level interfaces.
 
 use crate::{
-    data::{Datum, RawStr, RawString},
+    data::{Case, Datum, RawStr, RawString},
     dictionary::{VarType, VarWidth},
     endian::{Endian, Parse, ToBytes},
     format::DisplayPlainF64,
@@ -898,12 +898,12 @@ impl Datum {
         reader: &mut R,
         case_vars: &[CaseVar],
         endian: Endian,
-    ) -> Result<Option<Vec<Self>>, Error> {
+    ) -> Result<Option<Case>, Error> {
         fn eof<R: Seek>(
             reader: &mut R,
             case_vars: &[CaseVar],
             case_start: u64,
-        ) -> Result<Option<Vec<Datum>>, Error> {
+        ) -> Result<Option<Case>, Error> {
             let offset = reader.stream_position()?;
             if offset == case_start {
                 Ok(None)
@@ -943,7 +943,7 @@ impl Datum {
                 }
             }
         }
-        Ok(Some(values))
+        Ok(Some(Case(values)))
     }
 
     fn read_compressed_chunk<R: Read>(
@@ -975,12 +975,12 @@ impl Datum {
         codes: &mut VecDeque<u8>,
         endian: Endian,
         bias: f64,
-    ) -> Result<Option<Vec<Self>>, Error> {
+    ) -> Result<Option<Case>, Error> {
         fn eof<R: Seek>(
             reader: &mut R,
             case_start: u64,
             n_chunks: usize,
-        ) -> Result<Option<Vec<Datum>>, Error> {
+        ) -> Result<Option<Case>, Error> {
             let offset = reader.stream_position()?;
             if n_chunks > 0 {
                 Err(Error::EofInCompressedCase {
@@ -1028,7 +1028,7 @@ impl Datum {
                 }
             }
         }
-        Ok(Some(values))
+        Ok(Some(Case(values)))
     }
 }
 
@@ -1249,22 +1249,6 @@ where
 trait ReadSeek: Read + Seek {}
 impl<T> ReadSeek for T where T: Read + Seek {}
 
-/// A case in a system file.
-pub struct Case(
-    /// One [Datum] per variable in the system file dictionary, in the same
-    /// order:
-    ///
-    /// - A raw [Reader] returns cases in which very long string variables
-    ///   (those over 255 bytes wide) are still in their raw format, which means
-    ///   that they are divided into multiple, adjacent string variables,
-    ///   approximately one variable for each 252 bytes.
-    ///
-    /// - [Headers::decode](super::cooked::Headers::decode) returns cases in
-    ///   which each [Dictionary](crate::dictionary::Dictionary) variable
-    ///   corresponds to one [Datum], even for long string variables.
-    pub Vec<Datum>,
-);
-
 #[derive(Debug)]
 struct StringSegment {
     data_bytes: usize,
@@ -1328,6 +1312,15 @@ impl CaseVar {
 }
 
 /// Reader for cases in a system file.
+///
+/// - [Reader::cases] returns [Cases] in which very long string variables (those
+///   over 255 bytes wide) are still in their raw format, which means that they
+///   are divided into multiple, adjacent string variables, approximately one
+///   variable for each 252 bytes.
+///
+/// - [Headers::decode](super::cooked::Headers::decode) returns [Cases] in
+///   which each [Dictionary](crate::dictionary::Dictionary) variable
+///   corresponds to one [Datum], even for long string variables.
 pub struct Cases {
     reader: Box<dyn ReadSeek>,
     case_vars: Vec<CaseVar>,
@@ -1413,7 +1406,7 @@ impl Cases {
 }
 
 impl Iterator for Cases {
-    type Item = Result<Vec<Datum>, Error>;
+    type Item = Result<Case, Error>;
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.eof {
index e0fb088c9e9c64565047839c5b6f0a5964d0268c..a4f336bb7f86d48aeb6005c98879b6e1de24ed32 100644 (file)
@@ -672,7 +672,8 @@ where
                         case_numbers
                             .push(Value::new_integer(Some((case_numbers.len() + 1) as f64)));
                         data.push(
-                            case.into_iter()
+                            case.0
+                                .into_iter()
                                 .map(|datum| Value::new_datum(&datum, dictionary.encoding))
                                 .collect::<Vec<_>>(),
                         );