pub documents: Vec<String>,
/// Named collections of variables within the dictionary.
- pub vectors: HashSet<ByIdentifier<DictIndexVector>>,
+ vectors: HashSet<ByIdentifier<DictIndexVector>>,
/// Attributes for the dictionary itself.
///
/// Variable sets.
///
/// Only the GUI makes use of variable sets.
- pub variable_sets: Vec<DictIndexVariableSet>,
+ variable_sets: Vec<DictIndexVariableSet>,
/// Character encoding for the dictionary and the data.
- pub encoding: &'static Encoding,
+ encoding: &'static Encoding,
}
impl Serialize for Dictionary {
}
}
+ pub fn encoding(&self) -> &'static Encoding {
+ self.encoding
+ }
+
/// Returns a reference to the weight variable, if any.
pub fn weight_var(&self) -> Option<&Variable> {
self.weight.map(|index| &self.variables[index].0)
VariableSets::new(self)
}
+ pub fn add_variable_set(&mut self, set: DictIndexVariableSet) {
+ assert!(set
+ .variables
+ .iter()
+ .all(|dict_index| *dict_index < self.variables.len()));
+ self.variable_sets.push(set);
+ }
+
+ pub fn remove_variable_set(&mut self, var_set_index: usize) {
+ self.variable_sets.remove(var_set_index);
+ }
+
/// Adds `variable` at the end of the dictionary and returns its index.
///
/// The operation fails if the dictionary already contains a variable with
///
/// The variables in a [Dictionary] must all use the same encoding as the
/// dictionary.
- pub encoding: &'static Encoding,
+ encoding: &'static Encoding,
}
pub fn escape_value_label(unescaped: &str) -> Cow<'_, str> {
}
}
+ pub fn encoding(&self) -> &'static Encoding {
+ self.encoding
+ }
+
pub fn is_numeric(&self) -> bool {
self.width.is_numeric()
}
},
print_format: to_raw_format(variable.print_format, seg0_width),
write_format: to_raw_format(variable.write_format, seg0_width),
- name: encode_fixed_string(name0, variable.encoding),
+ name: encode_fixed_string(name0, variable.encoding()),
};
(2u32, record).write_le(self.writer)?;
// Variable label.
if let Some(label) = variable.label() {
- let label = variable.encoding.encode(&label).0;
+ let label = variable.encoding().encode(&label).0;
let len = label.len().min(255) as u32;
let padded_len = len.next_multiple_of(4);
(len, &*label, Zeros((padded_len - len) as usize)).write_le(self.writer)?;
missing_value_code: 0,
print_format: format,
write_format: format,
- name: encode_fixed_string(name, variable.encoding),
+ name: encode_fixed_string(name, variable.encoding()),
},
)
.write_le(self.writer)?;
// Label record.
(3u32, value_labels.0.len() as u32).write_le(self.writer)?;
for (datum, label) in &value_labels.0 {
- let label = &*self.dictionary.encoding.encode(&label).0;
+ let label = &*self.dictionary.encoding().encode(&label).0;
let label = if label.len() > 255 {
&label[..255]
} else {
if !self.dictionary.documents.is_empty() {
(6u32, self.dictionary.documents.len() as u32).write_le(self.writer)?;
for line in &self.dictionary.documents {
- Padded::exact(&*self.dictionary.encoding.encode(&line).0, 80, b' ')
+ Padded::exact(&*self.dictionary.encoding().encode(&line).0, 80, b' ')
.write_le(self.writer)?;
}
}
// We always write files in little-endian.
2
},
- character_code: codepage_from_encoding(self.dictionary.encoding) as i32,
+ character_code: codepage_from_encoding(self.dictionary.encoding()) as i32,
},
)
.write_le(self.writer)
fn write_var_sets(&mut self) -> Result<(), BinError> {
let mut s = String::new();
- for set in &self.dictionary.variable_sets {
- write!(&mut s, "{}= ", set.name).unwrap();
- for (index, variable) in set.variables.iter().enumerate() {
+ for set in &self.dictionary.variable_sets() {
+ write!(&mut s, "{}= ", set.name()).unwrap();
+ for (index, variable) in set.variables().iter().enumerate() {
let prefix = if index > 0 { " " } else { "" };
- write!(
- &mut s,
- "{prefix}{}",
- self.dictionary.variables[*variable].name
- )
- .unwrap();
+ write!(&mut s, "{prefix}{}", &variable.name).unwrap();
}
writeln!(&mut s).unwrap();
}
.iter()
.filter(|set| set.mr_type.supported_before_v14() == pre_v14)
{
- output.extend_from_slice(&self.dictionary.encoding.encode(&set.name).0[..]);
+ output.extend_from_slice(&self.dictionary.encoding().encode(&set.name).0[..]);
output.push(b'=');
match &set.mr_type {
MultipleResponseType::MultipleDichotomy { datum, labels } => {
let label = if set.mr_type.label_from_var_label() {
Cow::from(&[])
} else {
- self.dictionary.encoding.encode(&set.label).0
+ self.dictionary.encoding().encode(&set.label).0
};
write!(&mut output, "{} ", label.len()).unwrap();
output.extend_from_slice(&label[..]);
// might expand upon lowercasing.
let short_name = self.short_names[variable][0].as_str().to_ascii_lowercase();
output.push(b' ');
- output.extend_from_slice(&self.dictionary.encoding.encode(&short_name).0);
+ output.extend_from_slice(&self.dictionary.encoding().encode(&short_name).0);
}
output.push(b'\n');
}
if variable.value_labels.is_empty() || !variable.width.is_long_string() {
break;
}
- let name = self.dictionary.encoding.encode(&variable.name).0;
+ let name = self.dictionary.encoding().encode(&variable.name).0;
(
name.len() as u32,
&name[..],
for (value, label) in &variable.value_labels.0 {
let value = value.as_string().unwrap();
- let label = self.dictionary.encoding.encode(&label).0;
+ let label = self.dictionary.encoding().encode(&label).0;
(
value.len() as u32,
value.as_bytes(),
if variable.missing_values.is_empty() || !variable.width.is_long_string() {
break;
}
- let name = self.dictionary.encoding.encode(&variable.name).0;
+ let name = self.dictionary.encoding().encode(&variable.name).0;
(
name.len() as u32,
&name[..],
}
fn write_encoding(&mut self) -> Result<(), BinError> {
- self.write_string_record(20, self.dictionary.encoding.name())
+ self.write_string_record(20, self.dictionary.encoding().name())
}
fn write_bytes_record(&mut self, subtype: u32, bytes: &[u8]) -> Result<(), BinError> {
}
fn write_string_record(&mut self, subtype: u32, s: &str) -> Result<(), BinError> {
- self.write_bytes_record(subtype, &self.dictionary.encoding.encode(&s).0)
+ self.write_bytes_record(subtype, &self.dictionary.encoding().encode(&s).0)
}
}