};
use crate::{
- dictionary::{self, Dictionary},
+ dictionary::{self, Dictionary, VarWidth},
encoding::{default_encoding, get_encoding, Error as EncodingError},
endian::Endian,
format::{Error as FormatError, Spec, UncheckedSpec},
identifier::{Error as IdError, Identifier},
raw::{
self, LongStringMissingValueRecord, MissingValues, ProductInfoRecord, RawDocumentLine,
- RawStr, RawString, VarDisplayRecord, VarType,
+ RawStr, RawString, VarDisplayRecord, VarType, DecodedRecord,
},
};
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
pub fn decode(
- headers: Vec<raw::Record>,
- encoding: &'static Encoding,
- warn: &impl Fn(Error),
+ headers: Vec<DecodedRecord>,
+ decoder: raw::Decoder,
) -> Result<(Vec<Record>, Metadata), Error> {
+ let dictionary = Dictionary::new(decoder.encoding);
let mut decoder = Decoder {
- raw: raw::Decoder {
- encoding,
- warn: Box::new(|error| println!("{error}")),
- },
- encoding,
+ raw: decoder,
variables: HashMap::new(),
var_names: HashMap::new(),
- dictionary: Dictionary::new(encoding),
+ dictionary,
n_dict_indexes: 0,
n_generated_names: 0,
};
- let h = Headers::new(&headers, &decoder, warn);
+ let h = Headers::new(&headers, &decoder);
let Some(header) = h.header else {
return Err(Error::MissingHeaderRecord);
};
}
#[derive(Clone, Debug)]
-pub enum DecodedRecord<'a> {
- Header(HeaderRecord<Cow<'a, str>>),
- Variable(VariableRecord<Cow<'a, str>, String>),
- ValueLabel(ValueLabelRecord<RawStr<8>, Cow<'a, str>>),
- Document(DocumentRecord<Cow<'a, str>>),
+pub enum DecodedRecord {
+ Header(HeaderRecord<String>),
+ Variable(VariableRecord<String, String>),
+ ValueLabel(ValueLabelRecord<RawStr<8>, String>),
+ Document(DocumentRecord<String>),
IntegerInfo(IntegerInfoRecord),
FloatInfo(FloatInfoRecord),
VarDisplay(VarDisplayRecord),
- MultipleResponse(MultipleResponseRecord<Identifier, Cow<'a, str>>),
- LongStringValueLabels(LongStringValueLabelRecord<Identifier, Cow<'a, str>>),
+ MultipleResponse(MultipleResponseRecord<Identifier, String>),
+ LongStringValueLabels(LongStringValueLabelRecord<Identifier, String>),
LongStringMissingValues(LongStringMissingValueRecord<Identifier, String>),
Encoding(EncodingRecord),
NumberOfCases(NumberOfCasesRecord),
EndOfHeaders(u32),
ZHeader(ZHeader),
ZTrailer(ZTrailer),
+ Cases(Rc<RefCell<Cases>>),
}
impl Record {
}
}
- pub fn decode<'a>(&'a self, decoder: &Decoder) -> Result<DecodedRecord<'a>, Error> {
+ pub fn decode(&self, decoder: &Decoder) -> Result<DecodedRecord, Error> {
Ok(match self {
Record::Header(record) => record.decode(decoder),
Record::Variable(record) => record.decode(decoder),
Record::EndOfHeaders(record) => DecodedRecord::EndOfHeaders(*record),
Record::ZHeader(record) => DecodedRecord::ZHeader(record.clone()),
Record::ZTrailer(record) => DecodedRecord::ZTrailer(record.clone()),
- Record::Cases(_) => todo!(),
+ Record::Cases(record) => DecodedRecord::Cases(record.clone()),
})
}
}
})
}
- pub fn decode<'a>(&'a self, decoder: &Decoder) -> DecodedRecord<'a> {
- let eye_catcher = decoder.decode(&self.eye_catcher);
- let file_label = decoder.decode(&self.file_label);
- let creation_date = decoder.decode(&self.creation_date);
- let creation_time = decoder.decode(&self.creation_time);
+ pub fn decode(&self, decoder: &Decoder) -> DecodedRecord {
+ let eye_catcher = decoder.decode(&self.eye_catcher).to_string();
+ let file_label = decoder.decode(&self.file_label).to_string();
+ let creation_date = decoder.decode(&self.creation_date).to_string();
+ let creation_time = decoder.decode(&self.creation_time).to_string();
DecodedRecord::Header(HeaderRecord {
eye_catcher,
weight_index: self.weight_index,
DecodedRecord::Variable(VariableRecord {
offsets: self.offsets.clone(),
width: self.width,
- name: decoder.decode(&self.name),
+ name: decoder.decode(&self.name).to_string(),
print_format: self.print_format,
write_format: self.write_format,
missing_values: self.missing_values.decode(decoder),
- label: self.label.as_ref().map(|label| decoder.decode(label)),
+ label: self
+ .label
+ .as_ref()
+ .map(|label| decoder.decode(label).to_string()),
})
}
}
})))
}
- fn decode<'a>(&'a self, decoder: &Decoder) -> ValueLabelRecord<RawStr<8>, Cow<'a, str>> {
+ fn decode(&self, decoder: &Decoder) -> ValueLabelRecord<RawStr<8>, String> {
let labels = self
.labels
.iter()
.map(|ValueLabel { value, label }| ValueLabel {
value: *value,
- label: decoder.decode(label),
+ label: decoder.decode(label).to_string(),
})
.collect();
ValueLabelRecord {
lines: self
.lines
.iter()
- .map(|s| decoder.decode_slice(&s.0))
+ .map(|s| decoder.decode_slice(&s.0).to_string())
.collect(),
})
}
))
}
- fn decode<'a>(
- &'a self,
+ fn decode(
+ &self,
decoder: &Decoder,
- ) -> Result<MultipleResponseSet<Identifier, Cow<'a, str>>, Warning> {
+ ) -> Result<MultipleResponseSet<Identifier, String>, Warning> {
let mut short_names = Vec::with_capacity(self.short_names.len());
for short_name in self.short_names.iter() {
if let Some(short_name) = decoder
name: decoder
.decode_identifier(&self.name)
.map_err(Warning::InvalidMrSetVariableName)?,
- label: decoder.decode(&self.label),
+ label: decoder.decode(&self.label).to_string(),
mr_type: self.mr_type.clone(),
short_names,
})
}
impl LongStringValueLabels<RawString, RawString> {
- fn decode<'a>(
- &'a self,
+ fn decode(
+ &self,
decoder: &Decoder,
- ) -> Result<LongStringValueLabels<Identifier, Cow<'a, str>>, Warning> {
+ ) -> Result<LongStringValueLabels<Identifier, String>, Warning> {
let var_name = decoder.decode(&self.var_name);
let var_name = Identifier::new(var_name.trim_end(), decoder.encoding)
.map_err(Warning::InvalidLongStringValueLabelName)?;
let mut labels = Vec::with_capacity(self.labels.len());
for (value, label) in self.labels.iter() {
- let value = decoder.decode_exact_length(&value.0);
- let label = decoder.decode(label);
+ let value = decoder.decode_exact_length(&value.0).to_string();
+ let label = decoder.decode(label).to_string();
labels.push((value, label));
}
}
impl LongStringValueLabelRecord<RawString, RawString> {
- fn decode<'a>(
- &'a self,
- decoder: &Decoder,
- ) -> LongStringValueLabelRecord<Identifier, Cow<'a, str>> {
+ fn decode(&self, decoder: &Decoder) -> LongStringValueLabelRecord<Identifier, String> {
let mut labels = Vec::with_capacity(self.0.len());
for label in &self.0 {
match label.decode(decoder) {