rename value to datum
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 21 May 2025 00:03:39 +0000 (17:03 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 21 May 2025 00:03:39 +0000 (17:03 -0700)
rust/pspp/src/dictionary.rs
rust/pspp/src/format/display/mod.rs
rust/pspp/src/format/display/test.rs
rust/pspp/src/format/mod.rs
rust/pspp/src/format/parse.rs
rust/pspp/src/output/pivot/mod.rs
rust/pspp/src/sys/cooked.rs
rust/pspp/src/sys/raw.rs

index 6994d1289c67d61c2655570e3a7d672c8aca8d8b..12af9e6549806abfac8329ce94e1872c2a4c90b7 100644 (file)
@@ -21,9 +21,7 @@ use unicase::UniCase;
 use crate::{
     format::Format,
     identifier::{ByIdentifier, HasIdentifier, Identifier},
-    output::pivot::{
-        Axis3, Dimension, Footnote, Footnotes, Group, PivotTable, Value as PivotValue,
-    },
+    output::pivot::{Axis3, Dimension, Footnote, Footnotes, Group, PivotTable, Value},
     settings::Show,
     sys::raw::{Alignment, CategoryLabels, Measure, MissingValues, RawString, VarType},
 };
@@ -168,25 +166,25 @@ impl From<VarWidth> for VarType {
 }
 
 #[derive(Clone)]
-pub enum Value<S = RawString> {
+pub enum Datum<S = RawString> {
     Number(Option<f64>),
     String(S),
 }
 
-impl<S> Debug for Value<S>
+impl<S> Debug for Datum<S>
 where
     S: Debug,
 {
     fn fmt(&self, f: &mut Formatter) -> FmtResult {
         match self {
-            Value::Number(Some(number)) => write!(f, "{number:?}"),
-            Value::Number(None) => write!(f, "SYSMIS"),
-            Value::String(s) => write!(f, "{:?}", s),
+            Datum::Number(Some(number)) => write!(f, "{number:?}"),
+            Datum::Number(None) => write!(f, "SYSMIS"),
+            Datum::String(s) => write!(f, "{:?}", s),
         }
     }
 }
 
-impl PartialEq for Value {
+impl PartialEq for Datum {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
             (Self::Number(Some(l0)), Self::Number(Some(r0))) => {
@@ -199,78 +197,78 @@ impl PartialEq for Value {
     }
 }
 
-impl Eq for Value {}
+impl Eq for Datum {}
 
-impl PartialOrd for Value {
+impl PartialOrd for Datum {
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         Some(self.cmp(other))
     }
 }
 
-impl Ord for Value {
+impl Ord for Datum {
     fn cmp(&self, other: &Self) -> Ordering {
         match (self, other) {
-            (Value::Number(a), Value::Number(b)) => match (a, b) {
+            (Datum::Number(a), Datum::Number(b)) => match (a, b) {
                 (None, None) => Ordering::Equal,
                 (None, Some(_)) => Ordering::Less,
                 (Some(_), None) => Ordering::Greater,
                 (Some(a), Some(b)) => a.total_cmp(b),
             },
-            (Value::Number(_), Value::String(_)) => Ordering::Less,
-            (Value::String(_), Value::Number(_)) => Ordering::Greater,
-            (Value::String(a), Value::String(b)) => a.cmp(b),
+            (Datum::Number(_), Datum::String(_)) => Ordering::Less,
+            (Datum::String(_), Datum::Number(_)) => Ordering::Greater,
+            (Datum::String(a), Datum::String(b)) => a.cmp(b),
         }
     }
 }
 
-impl Hash for Value {
+impl Hash for Datum {
     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
         match self {
-            Value::Number(number) => number.map(OrderedFloat).hash(state),
-            Value::String(string) => string.hash(state),
+            Datum::Number(number) => number.map(OrderedFloat).hash(state),
+            Datum::String(string) => string.hash(state),
         }
     }
 }
 
-impl Value {
+impl Datum {
     pub const fn sysmis() -> Self {
         Self::Number(None)
     }
 
     pub fn as_number(&self) -> Option<Option<f64>> {
         match self {
-            Value::Number(number) => Some(*number),
-            Value::String(_) => None,
+            Datum::Number(number) => Some(*number),
+            Datum::String(_) => None,
         }
     }
 
     pub fn as_string(&self) -> Option<&RawString> {
         match self {
-            Value::Number(_) => None,
-            Value::String(s) => Some(s),
+            Datum::Number(_) => None,
+            Datum::String(s) => Some(s),
         }
     }
 }
 
-impl From<f64> for Value {
-    fn from(value: f64) -> Self {
-        Some(value).into()
+impl From<f64> for Datum {
+    fn from(number: f64) -> Self {
+        Some(number).into()
     }
 }
 
-impl From<Option<f64>> for Value {
+impl From<Option<f64>> for Datum {
     fn from(value: Option<f64>) -> Self {
         Self::Number(value)
     }
 }
 
-impl From<&str> for Value {
+impl From<&str> for Datum {
     fn from(value: &str) -> Self {
         value.as_bytes().into()
     }
 }
 
-impl From<&[u8]> for Value {
+impl From<&[u8]> for Datum {
     fn from(value: &[u8]) -> Self {
         Self::String(value.into())
     }
@@ -566,7 +564,7 @@ impl<'a> OutputVariables<'a> {
     pub fn to_pivot_table(&self) -> PivotTable {
         let mut names = Group::new("Name");
         for variable in &self.dictionary.variables {
-            names.push(PivotValue::new_variable(variable));
+            names.push(Value::new_variable(variable));
         }
 
         let mut attributes = Group::new("Attributes");
@@ -596,32 +594,24 @@ impl<'a> OutputVariables<'a> {
         pt
     }
 
-    fn get_field_value(
-        index: usize,
-        variable: &Variable,
-        field: VariableField,
-    ) -> Option<PivotValue> {
+    fn get_field_value(index: usize, variable: &Variable, field: VariableField) -> Option<Value> {
         match field {
-            VariableField::Position => Some(PivotValue::new_integer(Some(index as f64 + 1.0))),
-            VariableField::Label => variable
-                .label()
-                .map(|label| PivotValue::new_user_text(label)),
+            VariableField::Position => Some(Value::new_integer(Some(index as f64 + 1.0))),
+            VariableField::Label => variable.label().map(|label| Value::new_user_text(label)),
             VariableField::Measure => variable
                 .measure
-                .map(|measure| PivotValue::new_text(measure.as_str())),
-            VariableField::Role => Some(PivotValue::new_text(variable.role.as_str())),
-            VariableField::Width => {
-                Some(PivotValue::new_integer(Some(variable.display_width as f64)))
-            }
-            VariableField::Alignment => Some(PivotValue::new_text(variable.alignment.as_str())),
+                .map(|measure| Value::new_text(measure.as_str())),
+            VariableField::Role => Some(Value::new_text(variable.role.as_str())),
+            VariableField::Width => Some(Value::new_integer(Some(variable.display_width as f64))),
+            VariableField::Alignment => Some(Value::new_text(variable.alignment.as_str())),
             VariableField::PrintFormat => {
-                Some(PivotValue::new_user_text(variable.print_format.to_string()))
+                Some(Value::new_user_text(variable.print_format.to_string()))
             }
             VariableField::WriteFormat => {
-                Some(PivotValue::new_user_text(variable.write_format.to_string()))
+                Some(Value::new_user_text(variable.write_format.to_string()))
             }
             VariableField::MissingValues if !variable.missing_values.is_empty() => {
-                Some(PivotValue::new_user_text(
+                Some(Value::new_user_text(
                     variable
                         .missing_values
                         .display(variable.encoding)
@@ -660,7 +650,7 @@ impl<'a> OutputValueLabels<'a> {
             let mut values = variable.value_labels.iter().collect::<Vec<_>>();
             values.sort();
             for (value, label) in values {
-                let value = PivotValue::new_variable_value(variable, value)
+                let value = Value::new_variable_value(variable, value)
                     .with_show_value_label(Some(Show::Value));
                 //group.push();
                 todo!()
@@ -670,32 +660,24 @@ impl<'a> OutputValueLabels<'a> {
         todo!()
     }
 
-    fn get_field_value(
-        index: usize,
-        variable: &Variable,
-        field: VariableField,
-    ) -> Option<PivotValue> {
+    fn get_field_value(index: usize, variable: &Variable, field: VariableField) -> Option<Value> {
         match field {
-            VariableField::Position => Some(PivotValue::new_integer(Some(index as f64 + 1.0))),
-            VariableField::Label => variable
-                .label()
-                .map(|label| PivotValue::new_user_text(label)),
+            VariableField::Position => Some(Value::new_integer(Some(index as f64 + 1.0))),
+            VariableField::Label => variable.label().map(|label| Value::new_user_text(label)),
             VariableField::Measure => variable
                 .measure
-                .map(|measure| PivotValue::new_text(measure.as_str())),
-            VariableField::Role => Some(PivotValue::new_text(variable.role.as_str())),
-            VariableField::Width => {
-                Some(PivotValue::new_integer(Some(variable.display_width as f64)))
-            }
-            VariableField::Alignment => Some(PivotValue::new_text(variable.alignment.as_str())),
+                .map(|measure| Value::new_text(measure.as_str())),
+            VariableField::Role => Some(Value::new_text(variable.role.as_str())),
+            VariableField::Width => Some(Value::new_integer(Some(variable.display_width as f64))),
+            VariableField::Alignment => Some(Value::new_text(variable.alignment.as_str())),
             VariableField::PrintFormat => {
-                Some(PivotValue::new_user_text(variable.print_format.to_string()))
+                Some(Value::new_user_text(variable.print_format.to_string()))
             }
             VariableField::WriteFormat => {
-                Some(PivotValue::new_user_text(variable.write_format.to_string()))
+                Some(Value::new_user_text(variable.write_format.to_string()))
             }
             VariableField::MissingValues if !variable.missing_values.is_empty() => {
-                Some(PivotValue::new_user_text(
+                Some(Value::new_user_text(
                     variable
                         .missing_values
                         .display(variable.encoding)
@@ -881,7 +863,7 @@ pub struct Variable {
 
     /// Value labels, to associate a number (or a string) with a more meaningful
     /// description, e.g. 1 -> Apple, 2 -> Banana, ...
-    pub value_labels: HashMap<Value, String>,
+    pub value_labels: HashMap<Datum, String>,
 
     /// Variable label, an optional meaningful description for the variable
     /// itself.
@@ -1023,7 +1005,7 @@ pub enum MultipleResponseType {
     /// one value (the "counted value") means that the box was checked, and any
     /// other value means that it was not.
     MultipleDichotomy {
-        value: Value,
+        datum: Datum,
         labels: CategoryLabels,
     },
 
index b315c8873c91518e48c1a8ef65f5bb5c7a7b7c09..7f259b94ee672cd0fdc821df2d595d0f34f1ca54 100644 (file)
@@ -13,17 +13,17 @@ use smallvec::{Array, SmallVec};
 
 use crate::{
     calendar::{calendar_offset_to_gregorian, day_of_year, month_name, short_month_name},
-    dictionary::Value,
+    dictionary::Datum,
     endian::ToBytes,
     format::{Category, DateTemplate, Decimal, Format, NumberStyle, Settings, TemplateItem, Type},
     settings::{EndianSettings, Settings as PsppSettings},
 };
 
-pub struct DisplayValue<'a, 'b> {
+pub struct DisplayDatum<'a, 'b> {
     format: Format,
     settings: &'b Settings,
     endian: EndianSettings,
-    value: &'a Value,
+    datum: &'a Datum,
     encoding: &'static Encoding,
 }
 
@@ -58,32 +58,32 @@ impl Display for DisplayPlainF64 {
     }
 }
 
-impl Value {
-    /// Returns an object that implements [Display] for printing this `Value` as
-    /// `format`.  `encoding` specifies this `Value`'s encoding (therefore, it
-    /// is used only if this is a `Value::String`).
+impl Datum {
+    /// Returns an object that implements [Display] for printing this [Datum] as
+    /// `format`.  `encoding` specifies this `Datum`'s encoding (therefore, it
+    /// is used only if this is a `Datum::String`).
     ///
     /// [Display]: std::fmt::Display
-    pub fn display(&self, format: Format, encoding: &'static Encoding) -> DisplayValue {
-        DisplayValue::new(format, self, encoding)
+    pub fn display(&self, format: Format, encoding: &'static Encoding) -> DisplayDatum {
+        DisplayDatum::new(format, self, encoding)
     }
 
-    pub fn display_plain(&self, encoding: &'static Encoding) -> DisplayValuePlain {
-        DisplayValuePlain {
-            value: self,
+    pub fn display_plain(&self, encoding: &'static Encoding) -> DisplayDatumPlain {
+        DisplayDatumPlain {
+            datum: self,
             encoding,
             quote_strings: true,
         }
     }
 }
 
-pub struct DisplayValuePlain<'a> {
-    value: &'a Value,
+pub struct DisplayDatumPlain<'a> {
+    datum: &'a Datum,
     encoding: &'static Encoding,
     quote_strings: bool,
 }
 
-impl DisplayValuePlain<'_> {
+impl DisplayDatumPlain<'_> {
     pub fn without_quotes(self) -> Self {
         Self {
             quote_strings: false,
@@ -92,12 +92,12 @@ impl DisplayValuePlain<'_> {
     }
 }
 
-impl Display for DisplayValuePlain<'_> {
+impl Display for DisplayDatumPlain<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
-        match self.value {
-            Value::Number(None) => write!(f, "SYSMIS"),
-            Value::Number(Some(number)) => number.display_plain().fmt(f),
-            Value::String(string) => {
+        match self.datum {
+            Datum::Number(None) => write!(f, "SYSMIS"),
+            Datum::Number(Some(number)) => number.display_plain().fmt(f),
+            Datum::String(string) => {
                 if self.quote_strings {
                     write!(f, "\"{}\"", string.display(self.encoding))
                 } else {
@@ -108,11 +108,11 @@ impl Display for DisplayValuePlain<'_> {
     }
 }
 
-impl Display for DisplayValue<'_, '_> {
+impl Display for DisplayDatum<'_, '_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
-        let number = match self.value {
-            Value::Number(number) => *number,
-            Value::String(string) => {
+        let number = match self.datum {
+            Datum::Number(number) => *number,
+            Datum::String(string) => {
                 if self.format.type_() == Type::AHex {
                     for byte in &string.0 {
                         write!(f, "{byte:02x}")?;
@@ -167,12 +167,12 @@ impl Display for DisplayValue<'_, '_> {
     }
 }
 
-impl<'a, 'b> DisplayValue<'a, 'b> {
-    pub fn new(format: Format, value: &'a Value, encoding: &'static Encoding) -> Self {
+impl<'a, 'b> DisplayDatum<'a, 'b> {
+    pub fn new(format: Format, value: &'a Datum, encoding: &'static Encoding) -> Self {
         let settings = PsppSettings::global();
         Self {
             format,
-            value,
+            datum: value,
             encoding,
             settings: &settings.formats,
             endian: settings.endian,
@@ -639,7 +639,7 @@ impl<'a, 'b> DisplayValue<'a, 'b> {
     }
 
     fn to_binary(&self) -> Option<SmallVec<[u8; 16]>> {
-        let number = self.value.as_number()?;
+        let number = self.datum.as_number()?;
         match self.format.type_() {
             Type::P => Some(self.p(number)),
             Type::PK => Some(self.pk(number)),
index cae76487ba3a4de9e7bb51e0adcfe4d7105874be..0f581d6d61f2f3916ee631d800f234a21b6ccad2 100644 (file)
@@ -7,7 +7,7 @@ use smallstr::SmallString;
 use smallvec::SmallVec;
 
 use crate::{
-    dictionary::Value,
+    dictionary::Datum,
     endian::Endian,
     format::{AbstractFormat, Epoch, Format, Settings, Type, UncheckedFormat, CC},
     lex::{
@@ -63,7 +63,7 @@ fn test(name: &str) {
                 let format: Format = format.try_into().unwrap();
                 assert_eq!(tokens.get(1), Some(&Token::Punct(Punct::Colon)));
                 let expected = tokens[2].as_string().unwrap();
-                let actual = Value::Number(value)
+                let actual = Datum::Number(value)
                     .display(format, UTF_8)
                     .with_settings(&settings)
                     .with_endian(endian)
@@ -171,7 +171,7 @@ fn leading_zeros() {
         }
 
         fn test_with_settings(value: f64, expected: [&str; 2], settings: &Settings) {
-            let value = Value::from(value);
+            let value = Datum::from(value);
             for (expected, d) in expected.into_iter().zip([2, 1].into_iter()) {
                 assert_eq!(
                     &value
@@ -202,7 +202,7 @@ fn leading_zeros() {
 fn non_ascii_cc() {
     fn test(settings: &Settings, value: f64, expected: &str) {
         assert_eq!(
-            &Value::from(value)
+            &Datum::from(value)
                 .display(Format::new(Type::CC(CC::A), 10, 2).unwrap(), UTF_8)
                 .with_settings(settings)
                 .to_string(),
@@ -254,7 +254,7 @@ fn test_binhex(name: &str) {
                 assert_eq!(tokens.get(1), Some(&Token::Punct(Punct::Colon)));
                 let expected = tokens[2].as_string().unwrap();
                 let mut actual = SmallVec::<[u8; 16]>::new();
-                Value::Number(value)
+                Datum::Number(value)
                     .display(format, UTF_8)
                     .with_endian(endian)
                     .write(&mut actual, UTF_8)
index 51c06096d804c1ab897f95e5f000bfcb370d26f9..b7c3d81003b8a31d593b713bbcf4463da0e53d5a 100644 (file)
@@ -12,13 +12,13 @@ use thiserror::Error as ThisError;
 use unicode_width::UnicodeWidthStr;
 
 use crate::{
-    dictionary::{Value, VarWidth},
+    dictionary::{Datum, VarWidth},
     sys::raw::{self, RawString, VarType},
 };
 
 mod display;
 mod parse;
-pub use display::{DisplayPlain, DisplayValue};
+pub use display::{DisplayPlain, DisplayDatum};
 
 #[derive(Clone, ThisError, Debug, PartialEq, Eq)]
 pub enum Error {
@@ -374,10 +374,10 @@ impl Type {
         }
     }
 
-    pub fn default_value(&self) -> Value {
+    pub fn default_value(&self) -> Datum {
         match self.var_type() {
-            VarType::Numeric => Value::sysmis(),
-            VarType::String => Value::String(RawString::default()),
+            VarType::Numeric => Datum::sysmis(),
+            VarType::String => Datum::String(RawString::default()),
         }
     }
 }
@@ -596,10 +596,10 @@ impl Format {
         Ok(self)
     }
 
-    pub fn default_value(&self) -> Value {
+    pub fn default_value(&self) -> Datum {
         match self.var_width() {
-            VarWidth::Numeric => Value::sysmis(),
-            VarWidth::String(width) => Value::String(RawString::spaces(width as usize)),
+            VarWidth::Numeric => Datum::sysmis(),
+            VarWidth::String(width) => Datum::String(RawString::spaces(width as usize)),
         }
     }
 }
index 2f5887370f355916bea6b6b2ecf5020a67dd85a8..118cbe29825ef39343f6373799cb75a4a65a153a 100644 (file)
@@ -1,6 +1,6 @@
 use crate::{
     calendar::{calendar_gregorian_to_offset, DateError},
-    dictionary::Value,
+    dictionary::Datum,
     endian::{Endian, Parse},
     format::{DateTemplate, Decimals, Settings, TemplateItem, Type},
     settings::{EndianSettings, Settings as PsppSettings},
@@ -175,7 +175,7 @@ impl<'a> ParseValue<'a> {
     /// input into UTF-8, but this will screw up parsing of binary formats,
     /// because recoding bytes from (e.g.) windows-1252 into UTF-8, and then
     /// interpreting them as a binary number yields nonsense.
-    pub fn parse<'b, T>(&self, input: T) -> Result<Value, ParseError>
+    pub fn parse<'b, T>(&self, input: T) -> Result<Datum, ParseError>
     where
         T: Into<EncodedStr<'b>>,
     {
@@ -212,7 +212,7 @@ impl<'a> ParseValue<'a> {
             Type::IB => self.parse_ib(input.as_bytes()),
             Type::PIB => self.parse_pib(input.as_bytes()),
             Type::RB => self.parse_rb(input.as_bytes()),
-            Type::A => Ok(Value::String(
+            Type::A => Ok(Datum::String(
                 input.to_encoding(self.output_encoding).into(),
             )),
             Type::AHex => self.parse_ahex(&input.as_str()),
@@ -224,12 +224,12 @@ impl<'a> ParseValue<'a> {
         })
     }
 
-    fn parse_number(&self, input: &str, type_: Type) -> Result<Value, ParseErrorKind> {
+    fn parse_number(&self, input: &str, type_: Type) -> Result<Datum, ParseErrorKind> {
         let style = self.settings.number_style(type_);
 
         let input = input.trim();
         if input.is_empty() || input == "." {
-            return Ok(Value::sysmis());
+            return Ok(Datum::sysmis());
         }
         let mut p = StrParser::new(input.trim());
         fn strip_integer(mut input: &str, grouping: Option<char>) -> &str {
@@ -292,22 +292,22 @@ impl<'a> ParseValue<'a> {
         }
 
         match f64::from_str(&number) {
-            Ok(value) => Ok(Value::Number(Some(value))),
+            Ok(value) => Ok(Datum::Number(Some(value))),
             Err(_) => Err(ParseErrorKind::InvalidNumericSyntax),
         }
     }
 
-    fn parse_n(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_n(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         match input.chars().find(|c| !c.is_ascii_digit()) {
-            None => Ok(Value::Number(Some(input.parse().unwrap()))),
+            None => Ok(Datum::Number(Some(input.parse().unwrap()))),
             Some(nondigit) => Err(ParseErrorKind::Nondigit(nondigit)),
         }
     }
 
-    fn parse_z(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_z(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         let input = input.trim();
         if input.is_empty() || input == "." {
-            return Ok(Value::sysmis());
+            return Ok(Datum::sysmis());
         }
 
         enum ZChar {
@@ -361,7 +361,7 @@ impl<'a> ParseValue<'a> {
         } else {
             number
         };
-        Ok(Value::Number(Some(number)))
+        Ok(Datum::Number(Some(number)))
     }
 
     fn parse_bcd(input: &[u8]) -> Result<u128, ParseErrorKind> {
@@ -381,14 +381,14 @@ impl<'a> ParseValue<'a> {
         }
     }
 
-    fn parse_pk(&self, input: &[u8]) -> Result<Value, ParseErrorKind> {
+    fn parse_pk(&self, input: &[u8]) -> Result<Datum, ParseErrorKind> {
         let number = Self::parse_bcd(input)?;
-        Ok(Value::Number(Some(self.apply_decimals(number as f64))))
+        Ok(Datum::Number(Some(self.apply_decimals(number as f64))))
     }
 
-    fn parse_p(&self, input: &[u8]) -> Result<Value, ParseErrorKind> {
+    fn parse_p(&self, input: &[u8]) -> Result<Datum, ParseErrorKind> {
         if input.is_empty() {
-            return Ok(Value::Number(None));
+            return Ok(Datum::Number(None));
         };
         let (head, tail) = input.split_at(input.len() - 1);
         let number = Self::parse_bcd(head)?;
@@ -398,7 +398,7 @@ impl<'a> ParseValue<'a> {
             0xd => -(number as f64),
             other => return Err(ParseErrorKind::InvalidBCDSign(other)),
         };
-        Ok(Value::Number(Some(self.apply_decimals(number))))
+        Ok(Datum::Number(Some(self.apply_decimals(number))))
     }
 
     fn parse_binary(&self, input: &[u8]) -> u128 {
@@ -408,7 +408,7 @@ impl<'a> ParseValue<'a> {
         }
     }
 
-    fn parse_ib(&self, input: &[u8]) -> Result<Value, ParseErrorKind> {
+    fn parse_ib(&self, input: &[u8]) -> Result<Datum, ParseErrorKind> {
         let number = self.parse_binary(input);
         let sign_bit = 1 << (input.len() * 8 - 1);
         let number = if (number & sign_bit) == 0 {
@@ -416,15 +416,15 @@ impl<'a> ParseValue<'a> {
         } else {
             -(number.wrapping_sub(sign_bit << 1) as i128)
         };
-        Ok(Value::Number(Some(self.apply_decimals(number as f64))))
+        Ok(Datum::Number(Some(self.apply_decimals(number as f64))))
     }
 
-    fn parse_pib(&self, input: &[u8]) -> Result<Value, ParseErrorKind> {
+    fn parse_pib(&self, input: &[u8]) -> Result<Datum, ParseErrorKind> {
         let number = self.parse_binary(input);
-        Ok(Value::Number(Some(self.apply_decimals(number as f64))))
+        Ok(Datum::Number(Some(self.apply_decimals(number as f64))))
     }
 
-    fn parse_rb(&self, input: &[u8]) -> Result<Value, ParseErrorKind> {
+    fn parse_rb(&self, input: &[u8]) -> Result<Datum, ParseErrorKind> {
         let mut bytes = [0; 8];
         let len = input.len().min(8);
         bytes[..len].copy_from_slice(&input[..len]);
@@ -435,10 +435,10 @@ impl<'a> ParseValue<'a> {
             SYSMIS => None,
             other => Some(other),
         };
-        Ok(Value::Number(number))
+        Ok(Datum::Number(number))
     }
 
-    fn parse_ahex(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_ahex(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         let mut result = Vec::with_capacity(input.len() / 2);
         let mut iter = input.chars();
         while let Some(hi) = iter.next() {
@@ -453,7 +453,7 @@ impl<'a> ParseValue<'a> {
             };
             result.push((hi * 16 + lo) as u8);
         }
-        Ok(Value::String(result.into()))
+        Ok(Datum::String(result.into()))
     }
 
     fn parse_hex(&self, input: &str) -> Result<Option<u64>, ParseErrorKind> {
@@ -468,20 +468,20 @@ impl<'a> ParseValue<'a> {
         }
     }
 
-    fn parse_pibhex(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_pibhex(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         self.parse_hex(input)
-            .map(|value| Value::Number(value.map(|number| number as f64)))
+            .map(|value| Datum::Number(value.map(|number| number as f64)))
     }
 
-    fn parse_rbhex(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_rbhex(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         self.parse_hex(input)
-            .map(|value| Value::Number(value.map(f64::from_bits)))
+            .map(|value| Datum::Number(value.map(f64::from_bits)))
     }
 
-    fn parse_date(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_date(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         let mut p = StrParser(input.trim());
         if p.0.is_empty() || p.0 == "." {
-            return Ok(Value::sysmis());
+            return Ok(Datum::sysmis());
         }
 
         let mut day = 1;
@@ -566,7 +566,7 @@ impl<'a> ParseValue<'a> {
         } else {
             date + time
         };
-        Ok(Value::Number(Some(time_date)))
+        Ok(Datum::Number(Some(time_date)))
     }
 
     fn parse_minute_second(&self, p: &mut StrParser<'_>) -> Result<f64, ParseErrorKind> {
@@ -594,25 +594,25 @@ impl<'a> ParseValue<'a> {
         Ok(time + seconds)
     }
 
-    fn parse_wkday(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_wkday(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         let mut p = StrParser(input.trim());
         if p.0.is_empty() || p.0 == "." {
-            Ok(Value::sysmis())
+            Ok(Datum::sysmis())
         } else {
             let weekday = parse_weekday(&mut p)?;
             parse_trailer(&mut p)?;
-            Ok(Value::Number(Some(weekday as f64)))
+            Ok(Datum::Number(Some(weekday as f64)))
         }
     }
 
-    fn parse_month(&self, input: &str) -> Result<Value, ParseErrorKind> {
+    fn parse_month(&self, input: &str) -> Result<Datum, ParseErrorKind> {
         let mut p = StrParser(input.trim());
         if p.0.is_empty() || p.0 == "." {
-            Ok(Value::sysmis())
+            Ok(Datum::sysmis())
         } else {
             let month = parse_month(&mut p)?;
             parse_trailer(&mut p)?;
-            Ok(Value::Number(Some(month as f64)))
+            Ok(Datum::Number(Some(month as f64)))
         }
     }
 }
@@ -905,7 +905,7 @@ mod test {
 
     use crate::{
         calendar::{days_in_month, is_leap_year},
-        dictionary::Value,
+        dictionary::Datum,
         endian::Endian,
         format::{
             parse::{ParseError, ParseErrorKind, Sign},
@@ -1215,7 +1215,7 @@ mod test {
                     .with_settings(&settings)
                     .parse(&formatted)
                     .unwrap();
-                assert_eq!(parsed, Value::Number(Some(expected as f64)));
+                assert_eq!(parsed, Datum::Number(Some(expected as f64)));
             }
         }
 
@@ -1487,7 +1487,7 @@ mod test {
                 let parsed = Type::WkDay
                     .parser(UTF_8)
                     .parse(input)
-                    .unwrap_or(Value::Number(None))
+                    .unwrap_or(Datum::Number(None))
                     .as_number()
                     .unwrap();
                 assert_eq!(parsed, expected);
@@ -1560,7 +1560,7 @@ mod test {
                 let parsed = Type::Month
                     .parser(UTF_8)
                     .parse(input)
-                    .unwrap_or(Value::Number(None))
+                    .unwrap_or(Datum::Number(None))
                     .as_number()
                     .unwrap();
                 assert_eq!(parsed, expected, "parsing {input}");
@@ -1582,7 +1582,7 @@ mod test {
                 let s = [ac, bc].into_iter().collect::<String>();
                 let parsed = parser
                     .parse(&s)
-                    .unwrap_or(Value::Number(None))
+                    .unwrap_or(Datum::Number(None))
                     .as_number()
                     .unwrap();
                 let expected = if ac == 'x' || bc == 'x' {
@@ -1593,8 +1593,8 @@ mod test {
                 assert_eq!(parsed, expected);
             }
         }
-        assert_eq!(parser.parse(".").unwrap(), Value::Number(None));
-        assert_eq!(parser.parse("",).unwrap(), Value::Number(None));
+        assert_eq!(parser.parse(".").unwrap(), Datum::Number(None));
+        assert_eq!(parser.parse("",).unwrap(), Datum::Number(None));
     }
 
     #[test]
@@ -1683,7 +1683,7 @@ mod test {
                 assert_eq!(parsed, number as f64, "formatted as {formatted:?}");
             }
         }
-        assert_eq!(parser.parse(".").unwrap(), Value::Number(None));
+        assert_eq!(parser.parse(".").unwrap(), Datum::Number(None));
 
         let parser = Type::Z.parser(UTF_8).with_implied_decimals(1);
         for number in -999i32..=999 {
index e4225c73fac665ff179491ddb9784996c053771f..9973422221aa36b12ab8955ab2a11d1fb79c0413 100644 (file)
@@ -52,7 +52,7 @@ use thiserror::Error as ThisError;
 use tlo::parse_tlo;
 
 use crate::{
-    dictionary::{Value as DataValue, Variable},
+    dictionary::{Datum, Variable},
     format::{Decimal, Format, Settings as FormatSettings, Type, UncheckedFormat},
     settings::{Settings, Show},
     sys::raw::VarType,
@@ -1734,17 +1734,17 @@ impl Value {
             variable_label: variable.label.clone(),
         }))
     }
-    pub fn new_value(value: &DataValue, encoding: &'static Encoding) -> Self {
+    pub fn new_value(value: &Datum, encoding: &'static Encoding) -> Self {
         match value {
-            DataValue::Number(number) => Self::new_number(*number),
-            DataValue::String(string) => Self::new_user_text(string.decode(encoding).into_owned()),
+            Datum::Number(number) => Self::new_number(*number),
+            Datum::String(string) => Self::new_user_text(string.decode(encoding).into_owned()),
         }
     }
-    pub fn new_variable_value(variable: &Variable, value: &DataValue) -> Self {
+    pub fn new_variable_value(variable: &Variable, value: &Datum) -> Self {
         let var_name = Some(variable.name.as_str().into());
         let value_label = variable.value_labels.get(value).cloned();
         match value {
-            DataValue::Number(number) => Self::new(ValueInner::Number(NumberValue {
+            Datum::Number(number) => Self::new(ValueInner::Number(NumberValue {
                 show: None,
                 format: match variable.print_format.var_type() {
                     VarType::Numeric => variable.print_format,
@@ -1761,7 +1761,7 @@ impl Value {
                 var_name,
                 value_label,
             })),
-            DataValue::String(string) => Self::new(ValueInner::String(StringValue {
+            Datum::String(string) => Self::new(ValueInner::String(StringValue {
                 show: None,
                 hex: variable.print_format.type_() == Type::AHex,
                 s: string.decode(variable.encoding).into_owned(),
@@ -2060,12 +2060,7 @@ impl Display for DisplayValue<'_> {
                         *format
                     };
                     let mut buf = SmallString::<[u8; 40]>::new();
-                    write!(
-                        &mut buf,
-                        "{}",
-                        DataValue::Number(*value).display(format, UTF_8)
-                    )
-                    .unwrap();
+                    write!(&mut buf, "{}", Datum::Number(*value).display(format, UTF_8)).unwrap();
                     write!(f, "{}", buf.trim_start_matches(' '))?;
                 }
                 if let Some(label) = self.show_label {
index 7b4c5235f7c0f430ec37bdb9be9889d3736280b8..139a191682a368019c15c13f18dafec0ebd0b125 100644 (file)
@@ -3,7 +3,7 @@ use std::{cell::RefCell, collections::HashMap, ops::Range, rc::Rc};
 
 use crate::{
     dictionary::{
-        Dictionary, InvalidRole, MultipleResponseSet, MultipleResponseType, Value, VarWidth,
+        Dictionary, InvalidRole, MultipleResponseSet, MultipleResponseType, Datum, VarWidth,
         Variable, VariableSet,
     },
     endian::Endian,
@@ -600,7 +600,7 @@ pub fn decode(
 
         for dict_index in dict_indexes {
             let variable = dictionary.variables.get_index_mut2(dict_index).unwrap();
-            for ValueLabel { value, label } in record.labels.iter().cloned() {
+            for ValueLabel { datum: value, label } in record.labels.iter().cloned() {
                 let value = value.decode(variable.width);
                 variable.value_labels.insert(value, label);
             }
@@ -754,7 +754,7 @@ pub fn decode(
             // XXX warn about too-long value?
             value.0.resize(width, b' ');
             // XXX warn abouat duplicate value labels?
-            variable.value_labels.insert(Value::String(value), label);
+            variable.value_labels.insert(Datum::String(value), label);
         }
     }
 
@@ -773,7 +773,7 @@ pub fn decode(
             .map(|v| {
                 let mut value = RawString::from(v.0.as_slice());
                 value.resize(variable.width.as_string_width().unwrap());
-                Value::String(value)
+                Datum::String(value)
             })
             .collect::<Vec<_>>();
         variable.missing_values = MissingValues {
@@ -914,7 +914,7 @@ impl MultipleResponseType {
                                 number: string.into(),
                             }
                         })?;
-                        Value::Number(Some(number))
+                        Datum::Number(Some(number))
                     }
                     VarWidth::String(max_width) => {
                         let mut value = value.0.as_slice();
@@ -930,11 +930,11 @@ impl MultipleResponseType {
                                 max_width,
                             });
                         };
-                        Value::String(value.into())
+                        Datum::String(value.into())
                     }
                 };
                 Ok(MultipleResponseType::MultipleDichotomy {
-                    value,
+                    datum: value,
                     labels: *labels,
                 })
             }
index ad879dfa1b029b1117f6e67cafcca87878c4340d..50fbe9930bb0095250467d103601d0811e533728 100644 (file)
@@ -1,5 +1,5 @@
 use crate::{
-    dictionary::{Attributes, Value, VarWidth},
+    dictionary::{Attributes, Datum, VarWidth},
     endian::{Endian, Parse, ToBytes},
     format::DisplayPlain,
     identifier::{Error as IdError, Identifier},
@@ -707,13 +707,13 @@ impl TryFrom<RawWidth> for VarWidth {
     }
 }
 
-type RawValue = Value<RawStrArray<8>>;
+type RawDatum = Datum<RawStrArray<8>>;
 
-impl RawValue {
-    pub fn from_raw(raw: &UntypedValue, var_type: VarType, endian: Endian) -> Self {
+impl RawDatum {
+    pub fn from_raw(raw: &UntypedDatum, var_type: VarType, endian: Endian) -> Self {
         match var_type {
-            VarType::String => Value::String(RawStrArray(raw.0)),
-            VarType::Numeric => Value::Number(endian.parse(raw.0)),
+            VarType::String => Datum::String(RawStrArray(raw.0)),
+            VarType::Numeric => Datum::Number(endian.parse(raw.0)),
         }
     }
 
@@ -737,7 +737,7 @@ impl RawValue {
                     });
                 }
             };
-            values.push(Value::from_raw(&UntypedValue(raw), var_type, endian));
+            values.push(Datum::from_raw(&UntypedDatum(raw), var_type, endian));
         }
         Ok(Some(values))
     }
@@ -788,7 +788,7 @@ impl RawValue {
                         }
                     }
                     253 => {
-                        break Self::from_raw(&UntypedValue(read_bytes(reader)?), var_type, endian)
+                        break Self::from_raw(&UntypedDatum(read_bytes(reader)?), var_type, endian)
                     }
                     254 => match var_type {
                         VarType::String => break Self::String(RawStrArray(*b"        ")), // XXX EBCDIC
@@ -815,12 +815,12 @@ impl RawValue {
         Ok(Some(values))
     }
 
-    pub fn decode(&self, width: VarWidth) -> Value {
+    pub fn decode(&self, width: VarWidth) -> Datum {
         match self {
-            Self::Number(x) => Value::Number(*x),
+            Self::Number(x) => Datum::Number(*x),
             Self::String(s) => {
                 let width = width.as_string_width().unwrap();
-                Value::String(RawString::from(&s.0[..width]))
+                Datum::String(RawString::from(&s.0[..width]))
             }
         }
     }
@@ -1041,7 +1041,7 @@ impl Cases {
 }
 
 impl Iterator for Cases {
-    type Item = Result<Vec<RawValue>, Error>;
+    type Item = Result<Vec<RawDatum>, Error>;
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.eof {
@@ -1049,7 +1049,7 @@ impl Iterator for Cases {
         }
 
         let retval = if self.compression.is_some() {
-            Value::read_compressed_case(
+            Datum::read_compressed_case(
                 &mut self.reader,
                 &self.var_types,
                 &mut self.codes,
@@ -1058,7 +1058,7 @@ impl Iterator for Cases {
             )
             .transpose()
         } else {
-            Value::read_case(&mut self.reader, &self.var_types, self.endian).transpose()
+            Datum::read_case(&mut self.reader, &self.var_types, self.endian).transpose()
         };
         self.eof = matches!(retval, None | Some(Err(_)));
         retval
@@ -1124,7 +1124,7 @@ fn format_name(type_: u32) -> Cow<'static, str> {
 #[derive(Clone, Default)]
 pub struct MissingValues {
     /// Individual missing values, up to 3 of them.
-    pub values: Vec<Value>,
+    pub values: Vec<Datum>,
 
     /// Optional range of missing values.
     pub range: Option<MissingValueRange>,
@@ -1145,13 +1145,13 @@ impl MissingValues {
         self.values.is_empty() && self.range.is_none()
     }
 
-    pub fn contains(&self, value: &Value) -> bool {
+    pub fn contains(&self, value: &Datum) -> bool {
         if self.values.contains(value) {
             return true;
         }
 
         match value {
-            Value::Number(Some(number)) => self.range.is_some_and(|range| range.contains(*number)),
+            Datum::Number(Some(number)) => self.range.is_some_and(|range| range.contains(*number)),
             _ => false,
         }
     }
@@ -1188,7 +1188,7 @@ impl MissingValues {
             Ok(VarWidth::Numeric) => {
                 let values = values
                     .into_iter()
-                    .map(|v| Value::Number(endian.parse(v)))
+                    .map(|v| Datum::Number(endian.parse(v)))
                     .collect();
 
                 let range = range.map(|(low, high)| {
@@ -1201,7 +1201,7 @@ impl MissingValues {
                 let width = width.min(8) as usize;
                 let values = values
                     .into_iter()
-                    .map(|value| Value::String(RawString::from(&value[..width])))
+                    .map(|value| Datum::String(RawString::from(&value[..width])))
                     .collect();
                 return Ok(Self {
                     values,
@@ -1463,9 +1463,9 @@ impl VariableRecord<RawString> {
 }
 
 #[derive(Copy, Clone)]
-pub struct UntypedValue(pub [u8; 8]);
+pub struct UntypedDatum(pub [u8; 8]);
 
-impl Debug for UntypedValue {
+impl Debug for UntypedDatum {
     fn fmt(&self, f: &mut Formatter) -> FmtResult {
         let little: f64 = Endian::Little.parse(self.0);
         let little = format!("{:?}", little);
@@ -1724,7 +1724,7 @@ where
     V: Debug,
     S: Debug,
 {
-    pub value: Value<V>,
+    pub datum: Datum<V>,
     pub label: S,
 }
 
@@ -1796,7 +1796,7 @@ impl ValueLabelRecord<RawStrArray<8>, RawString> {
 
         let mut labels = Vec::new();
         for _ in 0..n {
-            let value = UntypedValue(read_bytes(r)?);
+            let value = UntypedDatum(read_bytes(r)?);
             let label_len: u8 = endian.parse(read_bytes(r)?);
             let label_len = label_len as usize;
             let padded_len = Integer::next_multiple_of(&(label_len + 1), &8);
@@ -1872,7 +1872,7 @@ impl ValueLabelRecord<RawStrArray<8>, RawString> {
         let labels = labels
             .into_iter()
             .map(|(value, label)| ValueLabel {
-                value: Value::from_raw(&value, var_type, endian),
+                datum: Datum::from_raw(&value, var_type, endian),
                 label,
             })
             .collect();
@@ -1890,10 +1890,15 @@ impl ValueLabelRecord<RawStrArray<8>, RawString> {
         let labels = self
             .labels
             .iter()
-            .map(|ValueLabel { value, label }| ValueLabel {
-                value: value.clone(),
-                label: decoder.decode(label).to_string(),
-            })
+            .map(
+                |ValueLabel {
+                     datum: value,
+                     label,
+                 }| ValueLabel {
+                    datum: value.clone(),
+                    label: decoder.decode(label).to_string(),
+                },
+            )
             .collect();
         ValueLabelRecord {
             offsets: self.offsets.clone(),