#![allow(dead_code)]
-use std::{borrow::Cow, sync::Arc};
+use std::{
+ borrow::Cow,
+ sync::{Arc, OnceLock},
+};
+use enum_map::EnumMap;
use pivot::PivotTable;
-use crate::message::Diagnostic;
+use crate::{
+ message::Diagnostic,
+ output::pivot::{Axis3, BorderStyle, Dimension, Group, Look},
+};
use self::pivot::Value;
}
}
+#[derive(Clone, Debug)]
pub struct Text {
type_: TextType,
}
}
+fn text_item_table_look() -> Arc<Look> {
+ static LOOK: OnceLock<Arc<Look>> = OnceLock::new();
+ LOOK.get_or_init(|| {
+ Arc::new({
+ let mut look = Look::default().with_borders(EnumMap::from_fn(|_| BorderStyle::none()));
+ for style in look.areas.values_mut() {
+ style.cell_style.margins = EnumMap::from_fn(|_| [0, 0]);
+ }
+ look
+ })
+ })
+ .clone()
+}
+
+impl From<Text> for PivotTable {
+ fn from(value: Text) -> Self {
+ let dimension =
+ Dimension::new(Group::new(Value::new_text("Text")).with(Value::new_user_text("null")))
+ .with_all_labels_hidden();
+ PivotTable::new([(Axis3::Y, dimension)])
+ .with_look(text_item_table_look())
+ .with_data([(&[0], value.content)])
+ .with_subtype(Value::new_user_text("Text"))
+ }
+}
+
impl From<&Diagnostic> for Text {
fn from(value: &Diagnostic) -> Self {
Self::new_log(value.to_string())
}
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum TextType {
/// `TITLE` and `SUBTITLE` commands.
PageTitle,
pub fn leaf_path(&self, index: usize) -> Option<Path<'_>> {
self.root.leaf_path(index, SmallVec::new())
}
+
+ pub fn with_all_labels_hidden(self) -> Self {
+ Self {
+ hide_all_labels: true,
+ ..self
+ }
+ }
}
#[derive(Clone, Debug)]
self
}
+ pub fn with_subtype(self, subtype: Value) -> Self {
+ Self {
+ subtype: Some(Box::new(subtype)),
+ ..self
+ }
+ }
+
pub fn with_show_title(mut self, show_title: bool) -> Self {
self.show_title = show_title;
self
self.cells.get(&self.cell_index(data_indexes))
}
- pub fn with_data<I>(mut self, iter: impl Iterator<Item = (I, Value)>) -> Self
+ pub fn with_data<I>(mut self, iter: impl IntoIterator<Item = (I, Value)>) -> Self
where
I: AsRef<[usize]>,
{
Details::Message(_diagnostic) => todo!(),
Details::PageBreak => Ok(()),
Details::Table(pivot_table) => self.render_table(&*pivot_table, writer),
- Details::Text(_text) => todo!(),
+ Details::Text(text) => self.render_table(&PivotTable::from((**text).clone()), writer),
}
}
test_sysfile("attributes");
}
+#[test]
+fn variable_roles() {
+ test_sysfile("variable_roles");
+}
+
+#[test]
+fn compressed_data() {
+ test_sysfile("compressed_data");
+}
+
fn test_sysfile(name: &str) {
let input_filename = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/sys/testdata")
--- /dev/null
+╭──────────────────────┬────────────────────────╮
+│ Created │ 01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product │PSPP synthetic test file│
+├──────────────────────┼────────────────────────┤
+│ Compression │SAV │
+│ Number of Cases│Unknown │
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬────────────────────────╮
+│Label │PSPP synthetic test file│
+│Variables│ 5│
+╰─────────┴────────────────────────╯
+
+╭─────┬────────┬─────┬─────────────────┬─────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│ │Position│Label│Measurement Level│ Role│Width│Alignment│Print Format│Write Format│Missing Values│
+├─────┼────────┼─────┼─────────────────┼─────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│num1 │ 1│ │ │Input│ 8│Right │F8.0 │F8.0 │ │
+│num2 │ 2│ │ │Input│ 8│Right │F8.0 │F8.0 │ │
+│str4 │ 3│ │Nominal │Input│ 4│Left │A4 │A4 │ │
+│str8 │ 4│ │Nominal │Input│ 8│Left │A8 │A8 │ │
+│str15│ 5│ │Nominal │Input│ 15│Left │A15 │A15 │ │
+╰─────┴────────┴─────┴─────────────────┴─────┴─────┴─────────┴────────────┴────────────┴──────────────╯
--- /dev/null
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+6; # Nominal case size
+1; # Simple compression
+0; # Not weighted
+-1; # Unspecified number of cases.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Numeric variables.
+2; 0; 0; 0; 0x050800 *2; s8 "NUM1";
+2; 0; 0; 0; 0x050800 *2; s8 "NUM2";
+
+# String variable.
+2; 4; 0; 0; 0x010400 *2; s8 "STR4";
+2; 8; 0; 0; 0x010800 *2; s8 "STR8";
+2; 15; 0; 0; 0x010f00 *2; s8 "STR15";
+2; -1; 0; 0; 0; 0; s8 "";
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;
+
+# Compressed data.
+i8 1 100 254 253 254 253; i8 255 251; "abcdefgh"; s8 "0123";
+i8 253 253 253 254; i8 101 102 253 253; s8 "jklm"; s8 "nopqrstu";
+s8 "vwxyzABC"; s8 "DEFG"; s8 "HIJKLMNO";
+i8 254 253 252 0 0 0 0 0; s8 "PQRSTUVW";
--- /dev/null
+Unknown role "6".
+
+╭──────────────────────┬────────────────────────╮
+│ Created │ 01-JAN-2011 20:53:52│
+├──────────────────────┼────────────────────────┤
+│Writer Product │PSPP synthetic test file│
+│ Version │1.2.3 │
+├──────────────────────┼────────────────────────┤
+│ Compression │None │
+│ Number of Cases│ 0│
+╰──────────────────────┴────────────────────────╯
+
+╭─────────┬────────────────────────╮
+│Label │PSPP synthetic test file│
+│Variables│ 7│
+╰─────────┴────────────────────────╯
+
+╭─┬────────┬─────┬─────────────────┬─────────┬─────┬─────────┬────────────┬────────────┬──────────────╮
+│ │Position│Label│Measurement Level│ Role │Width│Alignment│Print Format│Write Format│Missing Values│
+├─┼────────┼─────┼─────────────────┼─────────┼─────┼─────────┼────────────┼────────────┼──────────────┤
+│i│ 1│ │ │Input │ 8│Right │F8.0 │F8.0 │ │
+│o│ 2│ │ │Target │ 8│Right │F8.0 │F8.0 │ │
+│b│ 3│ │ │Both │ 8│Right │F8.0 │F8.0 │ │
+│n│ 4│ │ │None │ 8│Right │F8.0 │F8.0 │ │
+│p│ 5│ │ │Partition│ 8│Right │F8.0 │F8.0 │ │
+│s│ 6│ │ │Split │ 8│Right │F8.0 │F8.0 │ │
+│x│ 7│ │ │Input │ 8│Right │F8.0 │F8.0 │ │
+╰─┴────────┴─────┴─────────────────┴─────────┴─────┴─────────┴────────────┴────────────┴──────────────╯
+
+╭────────────────────────┬─────╮
+│Variable and Name │Value│
+├────────────────────────┼─────┤
+│i $@Role│0 │
+├────────────────────────┼─────┤
+│o $@Role│1 │
+├────────────────────────┼─────┤
+│b $@Role│2 │
+├────────────────────────┼─────┤
+│n $@Role│3 │
+├────────────────────────┼─────┤
+│p $@Role│4 │
+├────────────────────────┼─────┤
+│s $@Role│5 │
+├────────────────────────┼─────┤
+│x $@Role│6 │
+╰────────────────────────┴─────╯
--- /dev/null
+# File header.
+"$FL2"; s60 "$(#) SPSS DATA FILE PSPP synthetic test file";
+2; # Layout code
+7; # Nominal case size
+0; # Not compressed
+0; # Not weighted
+0; # 1 case.
+100.0; # Bias.
+"01 Jan 11"; "20:53:52"; s64 "PSPP synthetic test file";
+i8 0 *3;
+
+# Variables.
+2; 0; 0; 0; 0x050800 *2; s8 "I";
+2; 0; 0; 0; 0x050800 *2; s8 "O";
+2; 0; 0; 0; 0x050800 *2; s8 "B";
+2; 0; 0; 0; 0x050800 *2; s8 "N";
+2; 0; 0; 0; 0x050800 *2; s8 "P";
+2; 0; 0; 0; 0x050800 *2; s8 "S";
+2; 0; 0; 0; 0x050800 *2; s8 "X";
+
+# Machine integer info record.
+7; 3; 4; 8; 1; 2; 3; -1; 1; 1; ENDIAN; 1252;
+
+# Variable attributes record.
+7; 18; 1; COUNT (
+"I:$@Role('0'"; i8 10; ")";
+"/O:$@Role('1'"; i8 10; ")";
+"/B:$@Role('2'"; i8 10; ")";
+"/N:$@Role('3'"; i8 10; ")";
+"/P:$@Role('4'"; i8 10; ")";
+"/S:$@Role('5'"; i8 10; ")";
+"/X:$@Role('6'"; i8 10; ")";
+);
+
+# Character encoding record.
+7; 20; 1; 12; "windows-1252";
+
+# Dictionary termination record.
+999; 0;