-pub struct VariableSet {
- pub name: String,
- pub vars: Vec<String>,
-}
-
-impl VariableSet {
- fn parse(input: &str) -> Result<Self, Error> {
- let (name, input) = input.split_once('=').ok_or(Error::TBD)?;
- let vars = input.split_ascii_whitespace().map(String::from).collect();
- Ok(VariableSet {
- name: name.into(),
- vars,
- })
- }
-}
-
-pub struct VariableSetRecord(Vec<VariableSet>);
-
-impl TextRecord for VariableSetRecord {
- const NAME: &'static str = "variable set";
- fn parse(input: &str, warn: impl Fn(Error)) -> Result<Self, Error> {
- let mut sets = Vec::new();
- for line in input.lines() {
- match VariableSet::parse(line) {
- Ok(set) => sets.push(set),
- Err(error) => warn(error),
- }
- }
- Ok(VariableSetRecord(sets))
- }
-}
-
-pub struct LongVariableName {
- pub short_name: String,
- pub long_name: String,
-}
-
-pub struct LongVariableNameRecord(Vec<LongVariableName>);
-
-impl TextRecord for LongVariableNameRecord {
- const NAME: &'static str = "long variable names";
- fn parse(input: &str, warn: impl Fn(Error)) -> Result<Self, Error> {
- let mut names = Vec::new();
- for pair in input.split('\t').filter(|s| !s.is_empty()) {
- if let Some((short_name, long_name)) = pair.split_once('=') {
- let name = LongVariableName {
- short_name: short_name.into(),
- long_name: long_name.into(),
- };
- names.push(name);
- } else {
- warn(Error::TBD)
- }
- }
- Ok(LongVariableNameRecord(names))
- }
-}
-
-pub struct VeryLongString {
- pub short_name: String,
- pub length: usize,
-}
-
-impl VeryLongString {
- fn parse(input: &str) -> Result<VeryLongString, Error> {
- let Some((short_name, length)) = input.split_once('=') else {
- return Err(Error::TBD);
- };
- let length: usize = length.parse().map_err(|_| Error::TBD)?;
- Ok(VeryLongString {
- short_name: short_name.into(),
- length,
- })
- }
-}
-
-pub struct VeryLongStringRecord(Vec<VeryLongString>);
-
-impl TextRecord for VeryLongStringRecord {
- const NAME: &'static str = "very long strings";
- fn parse(input: &str, warn: impl Fn(Error)) -> Result<Self, Error> {
- let mut very_long_strings = Vec::new();
- for tuple in input
- .split('\0')
- .map(|s| s.trim_end_matches('\t'))
- .filter(|s| !s.is_empty())
- {
- match VeryLongString::parse(tuple) {
- Ok(vls) => very_long_strings.push(vls),
- Err(error) => warn(error),
- }
- }
- Ok(VeryLongStringRecord(very_long_strings))
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct LongStringValueLabels {
- pub var_name: UnencodedString,
- pub width: u32,
-
- /// `(value, label)` pairs, where each value is `width` bytes.
- pub labels: Vec<(UnencodedString, UnencodedString)>,
-}
-
-#[derive(Clone, Debug)]
-pub struct LongStringValueLabelRecord(Vec<LongStringValueLabels>);
-
-impl ExtensionRecord for LongStringValueLabelRecord {
- const SUBTYPE: u32 = 21;
- const SIZE: Option<u32> = Some(1);
- const COUNT: Option<u32> = None;
- const NAME: &'static str = "long string value labels record";
-
- fn parse(ext: &Extension, endian: Endian, _warn: impl Fn(Error)) -> Result<Self, Error> {
- ext.check_size::<Self>()?;
-
- let mut input = &ext.data[..];
- let mut label_set = Vec::new();
- while !input.is_empty() {
- let var_name = read_string(&mut input, endian)?;
- let width: u32 = endian.parse(read_bytes(&mut input)?);
- let n_labels: u32 = endian.parse(read_bytes(&mut input)?);
- let mut labels = Vec::new();
- for _ in 0..n_labels {
- let value = read_string(&mut input, endian)?;
- let label = read_string(&mut input, endian)?;
- labels.push((value, label));
- }
- label_set.push(LongStringValueLabels {
- var_name,
- width,
- labels,
- })
- }
- Ok(LongStringValueLabelRecord(label_set))
- }
-}
-