work
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 12 May 2025 16:10:58 +0000 (09:10 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 12 May 2025 16:10:58 +0000 (09:10 -0700)
rust/pspp/src/output/pivot/mod.rs
rust/pspp/src/output/spv.rs

index 2d5d3683cc25bcd80713dbf130d3adef8b52b764..02ec83193eac2dc0a22463112c3285c226ace72e 100644 (file)
@@ -283,14 +283,14 @@ impl PivotTable {
             Class::Residual => Format::F40_2,
             Class::Count => Format::F40, // XXX
         };
-        let value = Value::new(ValueInner::Number {
+        let value = Value::new(ValueInner::Number(NumberValue {
             show: None,
             format,
             honor_small: class == Class::Other,
             value: number,
             var_name: None,
             value_label: None,
-        });
+        }));
         self.insert(data_indexes, value);
     }
 
@@ -1669,14 +1669,14 @@ impl Value {
         }
     }
     fn new_number_with_format(x: Option<f64>, format: Format) -> Self {
-        Self::new(ValueInner::Number {
+        Self::new(ValueInner::Number(NumberValue {
             show: None,
             format,
             honor_small: false,
             value: x,
             var_name: None,
             value_label: None,
-        })
+        }))
     }
     pub fn new_number(x: Option<f64>) -> Self {
         Self::new_number_with_format(x, Format::F8_2)
@@ -1689,12 +1689,12 @@ impl Value {
     }
     pub fn new_user_text(s: impl Into<String>) -> Self {
         let s: String = s.into();
-        Self::new(ValueInner::Text {
+        Self::new(ValueInner::Text(TextValue {
             user_provided: true,
             local: s.clone(),
             c: s.clone(),
             id: s.clone(),
-        })
+        }))
     }
     pub fn with_footnote(mut self, footnote: &Arc<Footnote>) -> Self {
         let footnotes = &mut self.styling.get_or_insert_default().footnotes;
@@ -1792,7 +1792,7 @@ impl<'a> DisplayValue<'a> {
 
     pub fn var_type(&self) -> VarType {
         match self.inner {
-            ValueInner::Number { .. } if self.show_label.is_none() => VarType::Numeric,
+            ValueInner::Number(NumberValue { .. }) if self.show_label.is_none() => VarType::Numeric,
             _ => VarType::String,
         }
     }
@@ -1919,12 +1919,12 @@ fn interpret_show(
 impl Display for DisplayValue<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self.inner {
-            ValueInner::Number {
+            ValueInner::Number(NumberValue {
                 format,
                 honor_small,
                 value,
                 ..
-            } => {
+            }) => {
                 if self.show_value {
                     let format = if format.type_() == Type::F
                         && *honor_small
@@ -1952,7 +1952,8 @@ impl Display for DisplayValue<'_> {
                 Ok(())
             }
 
-            ValueInner::String { s, .. } | ValueInner::Variable { var_name: s, .. } => {
+            ValueInner::String(StringValue { s, .. })
+            | ValueInner::Variable(VariableValue { var_name: s, .. }) => {
                 match (self.show_value, self.show_label) {
                     (true, None) => write!(f, "{s}"),
                     (false, Some(label)) => write!(f, "{label}"),
@@ -1961,7 +1962,7 @@ impl Display for DisplayValue<'_> {
                 }
             }
 
-            ValueInner::Text { local, .. } => {
+            ValueInner::Text(TextValue { local, .. }) => {
                 /*
                 if self
                     .inner
@@ -1974,7 +1975,9 @@ impl Display for DisplayValue<'_> {
                 f.write_str(local)
             }
 
-            ValueInner::Template { args, local, .. } => self.template(f, local, args),
+            ValueInner::Template(TemplateValue { args, local, .. }) => {
+                self.template(f, local, args)
+            }
 
             ValueInner::Empty => Ok(()),
         }?;
@@ -2010,45 +2013,60 @@ impl Debug for Value {
     }
 }
 
+#[derive(Clone, Debug)]
+pub struct NumberValue {
+    pub show: Option<Show>,
+    pub format: Format,
+    pub honor_small: bool,
+    pub value: Option<f64>,
+    pub var_name: Option<String>,
+    pub value_label: Option<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct StringValue {
+    pub show: Option<Show>,
+    pub hex: bool,
+
+    /// If `hex` is true, this string should already be hex digits
+    /// (otherwise it would be impossible to encode non-UTF-8 data).
+    pub s: String,
+    pub var_name: Option<String>,
+    pub value_label: Option<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct VariableValue {
+    pub show: Option<Show>,
+    pub var_name: String,
+    pub variable_label: Option<String>,
+}
+
+#[derive(Clone, Debug)]
+pub struct TextValue {
+    pub user_provided: bool,
+    /// Localized.
+    pub local: String,
+    /// English.
+    pub c: String,
+    /// Identifier.
+    pub id: String,
+}
+
+#[derive(Clone, Debug)]
+pub struct TemplateValue {
+    pub args: Vec<Vec<Value>>,
+    pub local: String,
+    pub id: String,
+}
+
 #[derive(Clone, Debug, Default)]
 pub enum ValueInner {
-    Number {
-        show: Option<Show>,
-        format: Format,
-        honor_small: bool,
-        value: Option<f64>,
-        var_name: Option<String>,
-        value_label: Option<String>,
-    },
-    String {
-        show: Option<Show>,
-        hex: bool,
-
-        /// If `hex` is true, this string should already be hex digits
-        /// (otherwise it would be impossible to encode non-UTF-8 data).
-        s: String,
-        var_name: Option<String>,
-        value_label: Option<String>,
-    },
-    Variable {
-        show: Option<Show>,
-        var_name: String,
-        variable_label: Option<String>,
-    },
-    Text {
-        user_provided: bool,
-        /// Localized.
-        local: String,
-        /// English.
-        c: String,
-        /// Identifier.
-        id: String,
-    },
-    Template {
-        args: Vec<Vec<Value>>,
-        local: String,
-        id: String,
-    },
+    Number(NumberValue),
+    String(StringValue),
+    Variable(VariableValue),
+    Text(TextValue),
+    Template(TemplateValue),
 
     #[default]
     Empty,
@@ -2060,9 +2078,9 @@ impl ValueInner {
     }
     fn show(&self) -> Option<Show> {
         match self {
-            ValueInner::Number { show, .. }
-            | ValueInner::String { show, .. }
-            | ValueInner::Variable { show, .. } => *show,
+            ValueInner::Number(NumberValue { show, .. })
+            | ValueInner::String(StringValue { show, .. })
+            | ValueInner::Variable(VariableValue { show, .. }) => *show,
             _ => None,
         }
     }
@@ -2073,7 +2091,8 @@ impl ValueInner {
 
     fn value_label(&self) -> Option<&str> {
         match self {
-            ValueInner::Number { value_label, .. } | ValueInner::String { value_label, .. } => {
+            ValueInner::Number(NumberValue { value_label, .. })
+            | ValueInner::String(StringValue { value_label, .. }) => {
                 value_label.as_ref().map(String::as_str)
             }
             _ => None,
@@ -2082,7 +2101,7 @@ impl ValueInner {
 
     fn variable_label(&self) -> Option<&str> {
         match self {
-            ValueInner::Variable { variable_label, .. } => {
+            ValueInner::Variable(VariableValue { variable_label, .. }) => {
                 variable_label.as_ref().map(String::as_str)
             }
             _ => None,
index e421b97da38f6edaada1ddd834080d0bad383586..c397beee4dee2b7a62d178f1484b84e946ea3c44 100644 (file)
@@ -21,8 +21,8 @@ use crate::{
     output::{
         driver::Driver,
         pivot::{
-            Axis2, CellStyle, Color, FontStyle, HeadingRegion, HorzAlign, PivotTable, Value,
-            ValueInner, ValueStyle, VertAlign,
+            Axis2, CellStyle, Color, FontStyle, HeadingRegion, HorzAlign, PivotTable, StringValue,
+            TemplateValue, TextValue, Value, ValueInner, ValueStyle, VariableValue, VertAlign,
         },
         Item,
     },
@@ -540,6 +540,15 @@ struct OptionalStyle<'a> {
     template: Option<&'a str>,
 }
 
+impl<'a> Default for OptionalStyle<'a> {
+    fn default() -> Self {
+        Self {
+            style: &None,
+            template: None,
+        }
+    }
+}
+
 impl<'a> BinWrite for OptionalStyle<'a> {
     type Args<'b> = ();
 
@@ -622,57 +631,46 @@ impl BinWrite for Value {
         args: Self::Args<'_>,
     ) -> binrw::BinResult<()> {
         match &self.inner {
-            ValueInner::Number {
-                show,
-                format,
-                honor_small,
-                value,
-                var_name,
-                value_label,
-            } => {
-                if var_name.is_some() || value_label.is_some() {
+            ValueInner::Number(number) => {
+                if number.var_name.is_some() || number.value_label.is_some() {
                     2u8.write_options(writer, endian, args)?;
                     //write_optional_style(self.styling.as_ref(),writer, endian, args)?;
                     (
                         SpvFormat {
-                            format: *format,
-                            honor_small: *honor_small,
+                            format: number.format,
+                            honor_small: number.honor_small,
                         },
-                        value.unwrap_or(-f64::MAX),
-                        SpvString::optional(var_name),
-                        SpvString::optional(value_label),
-                        Show::as_spv(show),
+                        number.value.unwrap_or(-f64::MAX),
+                        SpvString::optional(&number.var_name),
+                        SpvString::optional(&number.value_label),
+                        Show::as_spv(&number.show),
                     )
                         .write_options(writer, endian, args)?;
                 } else {
                     1u8.write_options(writer, endian, args)?;
                     //write_optional_style(self.styling.as_ref(),writer, endian, args)?;
-                    value
+                    number
+                        .value
                         .unwrap_or(-f64::MAX)
                         .write_options(writer, endian, args)?;
-                    Show::as_spv(show).write_options(writer, endian, args)?;
+                    Show::as_spv(&number.show).write_options(writer, endian, args)?;
                 }
             }
-            ValueInner::String {
-                show,
-                hex,
-                s,
-                var_name,
-                value_label,
-            } => todo!(),
-            ValueInner::Variable {
-                show,
-                var_name,
-                variable_label,
-            } => todo!(),
-            ValueInner::Text {
-                user_provided,
-                local,
-                c,
-                id,
-            } => todo!(),
-            ValueInner::Template { args, local, id } => todo!(),
-            ValueInner::Empty => todo!(),
+            ValueInner::String(_string) => todo!(),
+            ValueInner::Variable(_variable) => todo!(),
+            ValueInner::Text(_text) => todo!(),
+            ValueInner::Template(_template) => todo!(),
+            ValueInner::Empty => {
+                (
+                    3u8,
+                    SpvString(""),
+                    OptionalStyle::default(),
+                    SpvString(""),
+                    SpvString(""),
+                    Bool(true),
+                )
+                    .write_options(writer, endian, args)?;
+            }
         }
         Ok(())
     }