Cleanup.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 21 Dec 2024 21:37:30 +0000 (13:37 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 21 Dec 2024 21:37:30 +0000 (13:37 -0800)
rust/pspp/src/cooked.rs
rust/pspp/src/raw.rs

index f5cd59af93e6ec52b2e3a6adaeddf5bf545b9c41..b2ae515f8bfef6d50fcfbf72b0a547bc1633c5c8 100644 (file)
@@ -18,7 +18,6 @@ use crate::{
 use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
 use encoding_rs::Encoding;
 use indexmap::set::MutableValues;
-use num::Integer;
 use thiserror::Error as ThisError;
 
 pub use crate::raw::{CategoryLabels, Compression};
@@ -448,9 +447,14 @@ pub fn decode(
         n_generated_names: 0,
     };
 
-    let mut header_vars = headers.variable.iter().enumerate();
     let mut var_index_map = HashMap::new();
-    while let Some((value_index, input)) = header_vars.next() {
+    let mut value_index = 0;
+    for (index, input) in headers
+        .variable
+        .iter()
+        .enumerate()
+        .filter(|(_index, record)| record.width != -1)
+    {
         let name = trim_end_spaces(input.name.to_string());
         let name = match Identifier::from_encoding(&name, encoding) {
             Ok(name) => {
@@ -506,21 +510,22 @@ pub fn decode(
             },
         );
 
-        // Skip long string continuation records.
-        if input.width > 0 {
-            #[allow(unstable_name_collisions)]
-            for _ in 1..input.width.div_ceil(&8) {
-                if let Some((_, continuation)) = header_vars.next() {
-                    if continuation.width == -1 {
-                        continue;
-                    }
-                }
-                return Err(Error::TBD);
+        // Check for long string continuation records.
+        let n_values = input.n_values().unwrap();
+        for offset in 1..n_values {
+            if headers
+                .variable
+                .get(index + offset)
+                .is_none_or(|record| record.width != -1)
+            {
+                warn(Error::TBD);
+                break;
             }
         }
 
         let dict_index = dictionary.add_var(variable).unwrap();
         assert_eq!(var_index_map.insert(value_index, dict_index), None);
+        value_index += n_values;
     }
 
     if let Some(weight_index) = headers.header.weight_index {
index b8fc79e7cf249e2e9b90f6ce7a92e7e967766023..776677e56331256cf97113cc2320ae851b216318 100644 (file)
@@ -1267,6 +1267,20 @@ where
     pub label: Option<S>,
 }
 
+impl<S, V> VariableRecord<S, V>
+where
+    S: Debug,
+    V: Debug,
+{
+    pub fn n_values(&self) -> Option<usize> {
+        match self.width {
+            0 => Some(1),
+            1..=255 => Some((self.width as usize).div_ceil(8)),
+            _ => None,
+        }
+    }
+}
+
 impl<S, V> Debug for VariableRecord<S, V>
 where
     S: Debug,