work on dictionary reading
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 21 Dec 2024 20:19:38 +0000 (12:19 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 21 Dec 2024 20:19:38 +0000 (12:19 -0800)
rust/pspp/src/cooked.rs
rust/pspp/src/dictionary.rs
rust/pspp/src/identifier.rs
rust/pspp/src/main.rs
rust/pspp/src/raw.rs

index 7bfba78ecb951a009943c6c502ddc6f006f4c7b2..4d46dc4ead6b2a3e943fdef5d2b72f7d061eecc9 100644 (file)
@@ -552,7 +552,7 @@ pub fn decode(
         }
 
         for dict_index in dict_indexes {
-            let mut variable = &dictionary.variables[dict_index];
+            let variable = dictionary.variables.get_index_mut2(dict_index).unwrap();
             for ValueLabel { value, label } in record.labels.iter().cloned() {
                 let value = match value {
                     raw::Value::Number(number) => Value::Number(number.map(|n| n.into())),
@@ -560,6 +560,7 @@ pub fn decode(
                         string.0[..variable.width.as_string_width().unwrap()].into()
                     }
                 };
+                variable.value_labels.insert(value, label);
             }
         }
     }
index d4fdd6c458e4d30c7e1bd6d848f30268ec928444..e8dcec2f2051b7ddfdb995441bfd1c67c5eec477 100644 (file)
@@ -159,8 +159,17 @@ impl Ord for Value {
     }
 }
 
+impl Hash for Value {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        match self {
+            Value::Number(number) => number.map(|x| OrderedFloat(x)).hash(state),
+            Value::String(string) => string.hash(state),
+        }
+    }
+}
+
 impl Value {
-    fn sysmis() -> Self {
+    pub fn sysmis() -> Self {
         Self::Number(None)
     }
 }
index 2d5c0317ec4adf9c76bb6c96249b5312253617e6..c6909fd58afd095aa76bd407af44a59237688edd 100644 (file)
@@ -3,7 +3,7 @@ use std::{
     cmp::Ordering,
     fmt::{Debug, Display, Formatter, Result as FmtResult},
     hash::{Hash, Hasher},
-    ops::Deref,
+    ops::{Deref, DerefMut},
 };
 
 use encoding_rs::{EncoderResult, Encoding, UTF_8};
@@ -392,3 +392,12 @@ where
         &self.0
     }
 }
+
+impl<T> DerefMut for ByIdentifier<T>
+where
+    T: HasIdentifier + Clone,
+{
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
index 5fb57135f74232838a3659b9cc165b619ee9222c..62ab24337b076a090c4e21016c91ced4f2c7b4b2 100644 (file)
@@ -153,8 +153,8 @@ fn dissect(
             }
             let headers = Headers::new(decoded_records, &|e| eprintln!("{e}"))?;
             let (dictionary, metadata) = decode(headers, encoding, |e| eprintln!("{e}"))?;
-            println!("{dictionary:?}");
-            println!("{metadata:?}");
+            println!("{dictionary:#?}");
+            println!("{metadata:#?}");
         }
     }
 
index c9b04773ff6c8aa5b1ec6ee56f7f56eccc163bba..5b2a3eb55f898baa47263e43e9326a11885493dc 100644 (file)
@@ -1553,9 +1553,10 @@ impl ValueLabelRecord<RawStr<8>, RawString> {
         let index_offset = r.stream_position()?;
         let mut dict_indexes = Vec::with_capacity(n as usize);
         let mut invalid_indexes = Vec::new();
+        let valid_range = 1..=var_types.len();
         for _ in 0..n {
             let index: u32 = endian.parse(read_bytes(r)?);
-            if index == 0 || index as usize > var_types.len() {
+            if valid_range.contains(&(index as usize)) {
                 dict_indexes.push(index);
             } else {
                 invalid_indexes.push(index);