From d1a7348ea5d482a598ed6df647682bb73e1865d4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 13 Apr 2025 10:05:23 -0700 Subject: [PATCH] Use RawString instead of Box<[u8]> in Value. --- rust/pspp/src/cooked.rs | 4 +--- rust/pspp/src/dictionary.rs | 6 +++--- rust/pspp/src/format/display.rs | 8 ++++++-- rust/pspp/src/format/mod.rs | 4 ++-- rust/pspp/src/raw.rs | 10 ++++++++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/rust/pspp/src/cooked.rs b/rust/pspp/src/cooked.rs index 96d78ff1f2..7c68d47c8b 100644 --- a/rust/pspp/src/cooked.rs +++ b/rust/pspp/src/cooked.rs @@ -714,9 +714,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.0.into_boxed_slice()), label); + variable.value_labels.insert(Value::String(value), label); } } diff --git a/rust/pspp/src/dictionary.rs b/rust/pspp/src/dictionary.rs index 67d5539ba7..d6f0980c22 100644 --- a/rust/pspp/src/dictionary.rs +++ b/rust/pspp/src/dictionary.rs @@ -16,7 +16,7 @@ use unicase::UniCase; use crate::{ format::Format, identifier::{ByIdentifier, HasIdentifier, Identifier}, - raw::{Alignment, CategoryLabels, Measure, MissingValues, VarType}, + raw::{Alignment, CategoryLabels, Measure, MissingValues, RawString, VarType}, }; pub type DictIndex = usize; @@ -157,7 +157,7 @@ impl From for VarType { } #[derive(Clone)] -pub enum Value> { +pub enum Value { Number(Option), String(S), } @@ -233,7 +233,7 @@ impl Value { } } - pub fn as_string(&self) -> Option<&[u8]> { + pub fn as_string(&self) -> Option<&RawString> { match self { Value::Number(_) => None, Value::String(s) => Some(s), diff --git a/rust/pspp/src/format/display.rs b/rust/pspp/src/format/display.rs index 8955d6b7b9..6edf3dc9f3 100644 --- a/rust/pspp/src/format/display.rs +++ b/rust/pspp/src/format/display.rs @@ -44,11 +44,15 @@ impl Display for DisplayValue<'_, '_> { Value::Number(number) => *number, Value::String(string) => { if self.format.type_() == Type::AHex { - for byte in string { + for byte in &string.0 { write!(f, "{byte:02x}")?; } } else { - write!(f, "{}", self.encoding.decode_without_bom_handling(string).0)?; + write!( + f, + "{}", + self.encoding.decode_without_bom_handling(&string.0).0 + )?; } return Ok(()); } diff --git a/rust/pspp/src/format/mod.rs b/rust/pspp/src/format/mod.rs index 3b87aa4664..8f520266a6 100644 --- a/rust/pspp/src/format/mod.rs +++ b/rust/pspp/src/format/mod.rs @@ -13,7 +13,7 @@ use unicode_width::UnicodeWidthStr; use crate::{ dictionary::{Value, VarWidth}, - raw::{self, VarType}, + raw::{self, RawString, VarType}, }; mod display; @@ -592,7 +592,7 @@ impl Format { pub fn default_value(&self) -> Value { match self.var_width() { VarWidth::Numeric => Value::sysmis(), - VarWidth::String(width) => Value::String((0..width).map(|_| 0u8).collect()), + VarWidth::String(width) => Value::String(RawString::spaces(width as usize)), } } } diff --git a/rust/pspp/src/raw.rs b/rust/pspp/src/raw.rs index b8d0ea2cb9..b9f25230ad 100644 --- a/rust/pspp/src/raw.rs +++ b/rust/pspp/src/raw.rs @@ -770,7 +770,7 @@ impl RawValue { Self::Number(x) => Value::Number(*x), Self::String(s) => { let width = width.as_string_width().unwrap(); - Value::String(Box::from(&s.0[..width])) + Value::String(RawString::from(&s.0[..width])) } } } @@ -1370,9 +1370,15 @@ impl Debug for UntypedValue { } } -#[derive(Clone)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct RawString(pub Vec); +impl RawString { + pub fn spaces(n: usize) -> Self { + Self(std::iter::repeat_n(b' ', n).collect()) + } +} + impl From> for RawString { fn from(source: Vec) -> Self { Self(source) -- 2.30.2