3 use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
4 use encoding_rs::Encoding;
8 {endian::Endian, CategoryLabels, Compression},
13 pub compression: Option<Compression>,
15 pub encoding: &'static Encoding,
19 fn decode_string<'a>(&self, input: &'a [u8], warn: &impl Fn(Error)) -> Cow<'a, str> {
20 let (output, malformed) = self.encoding.decode_without_bom_handling(input);
28 pub trait Decode: Sized {
30 fn decode(decoder: &Decoder, input: &Self::Input, warn: impl Fn(Error)) -> Self;
35 pub eye_catcher: String,
36 pub weight_index: Option<usize>,
37 pub n_cases: Option<u64>,
38 pub creation: NaiveDateTime,
39 pub file_label: String,
42 impl Decode for Header {
43 type Input = crate::raw::Header;
45 fn decode(decoder: &Decoder, input: &Self::Input, warn: impl Fn(Error)) -> Self {
46 let eye_catcher = decoder.decode_string(&input.eye_catcher, &warn);
47 let file_label = decoder.decode_string(&input.file_label, &warn);
48 let creation_date = decoder.decode_string(&input.creation_date, &warn);
49 let creation_date = NaiveDate::parse_from_str(&creation_date, "%v").unwrap_or_else(|_| {
50 warn(Error::InvalidCreationDate {
51 creation_date: creation_date.into(),
55 let creation_time = decoder.decode_string(&input.creation_time, &warn);
57 NaiveTime::parse_from_str(&creation_time, "%H:%M:%S").unwrap_or_else(|_| {
58 warn(Error::InvalidCreationTime {
59 creation_time: creation_time.into(),
64 eye_catcher: eye_catcher.into(),
65 weight_index: input.weight_index.map(|n| n as usize),
66 n_cases: input.n_cases.map(|n| n as u64),
67 creation: NaiveDateTime::new(creation_date, creation_time),
68 file_label: file_label.into(),
76 pub print_format: Spec,
77 pub write_format: Spec,
81 pub struct Document(Vec<String>);
83 impl Decode for Document {
84 type Input = crate::raw::Document;
86 fn decode(decoder: &Decoder, input: &Self::Input, warn: impl Fn(Error)) -> Self {
91 .map(|s| decoder.decode_string(s, &warn).into())
97 pub use crate::raw::FloatInfo;
98 pub use crate::raw::IntegerInfo;
100 #[derive(Clone, Debug)]
101 pub enum MultipleResponseType {
104 labels: CategoryLabels,
108 #[derive(Clone, Debug)]
109 pub struct MultipleResponseSet {
112 pub mr_type: MultipleResponseType,
113 pub vars: Vec<String>,
116 #[derive(Clone, Debug)]
117 pub struct MultipleResponseRecord(Vec<MultipleResponseSet>);
119 #[derive(Clone, Debug)]
120 pub struct ProductInfo(String);
134 pub struct VarDisplay {
135 pub measure: Option<Measure>,
137 pub align: Option<Alignment>,
140 pub struct VarDisplayRecord(pub Vec<VarDisplay>);