-use std::{borrow::Cow, collections::{HashSet, HashMap}};
+use std::{borrow::Cow, collections::{HashSet, HashMap}, cmp::Ordering};
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
use encoding_rs::Encoding;
use num::integer::div_ceil;
use crate::{
- format::{Spec, UncheckedSpec, Width},
+ format::{Spec, UncheckedSpec},
identifier::{Error as IdError, Identifier},
- raw::{self, MissingValues},
+ raw::{self, MissingValues, VarType},
{endian::Endian, Compression},
};
use thiserror::Error as ThisError;
assert!(self.n_generated_names < usize::MAX);
}
}
- fn take_dict_indexes(&mut self, id: &Identifier, width: Width) -> usize {
+ fn take_dict_indexes(&mut self, id: &Identifier, width: VarWidth) -> usize {
let n = match width {
- 0 => 1,
- w => div_ceil(w, 8) as usize,
+ VarWidth::Numeric => 1,
+ VarWidth::String(w) => div_ceil(w as usize, 8),
};
let dict_index = self.n_dict_indexes;
self.dict_indexes.insert(self.n_dict_indexes, id.clone());
}
}
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum VarWidth {
+ Numeric,
+ String(u16),
+}
+
+impl PartialOrd for VarWidth {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match (self, other) {
+ (VarWidth::Numeric, VarWidth::Numeric) => Some(Ordering::Equal),
+ (VarWidth::String(a), VarWidth::String(b)) => Some(a.cmp(b)),
+ _ => None,
+ }
+ }
+}
+
+impl From<VarWidth> for VarType {
+ fn from(source: VarWidth) -> Self {
+ match source {
+ VarWidth::Numeric => VarType::Numeric,
+ VarWidth::String(_) => VarType::String,
+ }
+ }
+}
+
pub struct Variable {
- pub width: Width,
+ pub width: VarWidth,
pub name: Identifier,
pub print_format: Spec,
pub write_format: Spec,
pub label: Option<String>,
}
-fn decode_format(raw: raw::Spec, name: &str, width: Width) -> Spec {
+fn decode_format(raw: raw::Spec, name: &str, width: VarWidth) -> Spec {
UncheckedSpec::try_from(raw)
.and_then(Spec::try_from)
.and_then(|x| x.check_width_compatibility(Some(name), width))
input: &crate::raw::Variable,
warn: impl Fn(Error),
) -> Result<Option<Variable>, Error> {
- match input.width {
- 0..=255 => (),
+ let width = match input.width {
+ 0 => VarWidth::Numeric,
+ w @ 1..=255 => VarWidth::String(w as u16),
-1 => return Ok(None),
_ => {
return Err(Error::BadVariableWidth {
})
}
};
- let width = input.width as Width;
let name = decoder.decode_string(&input.name.0, &warn);
let name = match Identifier::new(&name, decoder.encoding) {
Ok(name) => {
}
}
+/*
+pub struct ValueLabelRecord {
+ pub labels: Vec<(
+}
+*/
pub struct VariableSetRecord(Vec<VariableSet>);
impl TextRecord for VariableSetRecord {