all the header records have parsers
authorBen Pfaff <blp@cs.stanford.edu>
Wed, 30 Aug 2023 15:29:46 +0000 (08:29 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Wed, 30 Aug 2023 15:29:46 +0000 (08:29 -0700)
rust/src/cooked.rs

index 58e9c270512f108a0178ec5c12f11b05163f7f58..30430c101e5c568c47bcec0d0148179272f216b6 100644 (file)
@@ -129,6 +129,9 @@ pub enum Error {
     #[error("Invalid variable name in long string value label record.  {0}")]
     InvalidLongStringValueLabelName(IdError),
 
+    #[error("Invalid variable name in attribute record.  {0}")]
+    InvalidAttributeVariableName(IdError),
+
     #[error("Details TBD")]
     TBD,
 }
@@ -151,7 +154,7 @@ pub enum Record {
     LongNames(LongNameRecord),
     VeryLongStrings(VeryLongStringRecord),
     FileAttributes(FileAttributeRecord),
-    //VariableAttributes(UnencodedString),
+    VariableAttributes(VariableAttributeRecord),
     //OtherExtension(Extension),
     //EndOfHeaders(u32),
     //ZHeader(ZHeader),
@@ -842,8 +845,9 @@ impl FileAttributeRecord {
     }
 }
 
+#[derive(Clone, Debug)]
 pub struct VarAttributeSet {
-    pub long_var_name: String,
+    pub long_var_name: Identifier,
     pub attributes: AttributeSet,
 }
 
@@ -852,21 +856,23 @@ impl VarAttributeSet {
         decoder: &Decoder,
         input: &'a str,
         warn: &impl Fn(Error),
-    ) -> Result<(VarAttributeSet, &'a str), Error> {
+    ) -> Result<(Option<VarAttributeSet>, &'a str), Error> {
         let Some((long_var_name, rest)) = input.split_once(':') else {
             return Err(Error::TBD);
         };
         let (attributes, rest) = AttributeSet::parse(decoder, rest, Some('/'), warn)?;
-        Ok((
-            VarAttributeSet {
-                long_var_name: long_var_name.into(),
+        let var_attribute = Identifier::new(long_var_name, decoder.encoding)
+            .map_err(|e| Error::InvalidAttributeVariableName(e))
+            .warn_on_error(warn)
+            .map(|name| VarAttributeSet {
+                long_var_name: name,
                 attributes,
-            },
-            rest,
-        ))
+            });
+        Ok((var_attribute, rest))
     }
 }
 
+#[derive(Clone, Debug)]
 pub struct VariableAttributeRecord(Vec<VarAttributeSet>);
 
 impl VariableAttributeRecord {
@@ -878,7 +884,9 @@ impl VariableAttributeRecord {
             else {
                 break;
             };
-            var_attribute_sets.push(var_attribute);
+            if let Some(var_attribute) = var_attribute {
+                var_attribute_sets.push(var_attribute);
+            }
             input = rest;
         }
         Ok(VariableAttributeRecord(var_attribute_sets))