// 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);
         }
     }
 
 
 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;
 }
 
 #[derive(Clone)]
-pub enum Value<S = Box<[u8]>> {
+pub enum Value<S = RawString> {
     Number(Option<f64>),
     String(S),
 }
         }
     }
 
-    pub fn as_string(&self) -> Option<&[u8]> {
+    pub fn as_string(&self) -> Option<&RawString> {
         match self {
             Value::Number(_) => None,
             Value::String(s) => Some(s),
 
             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(());
             }
 
 
 use crate::{
     dictionary::{Value, VarWidth},
-    raw::{self, VarType},
+    raw::{self, RawString, VarType},
 };
 
 mod display;
     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)),
         }
     }
 }
 
             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]))
             }
         }
     }
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct RawString(pub Vec<u8>);
 
+impl RawString {
+    pub fn spaces(n: usize) -> Self {
+        Self(std::iter::repeat_n(b' ', n).collect())
+    }
+}
+
 impl From<Vec<u8>> for RawString {
     fn from(source: Vec<u8>) -> Self {
         Self(source)