variable sets
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 22 Dec 2023 20:47:18 +0000 (12:47 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 22 Dec 2023 20:47:18 +0000 (12:47 -0800)
rust/src/raw.rs

index e0c5a79efff97e3c8f228d7677f791077260673e..ac2d1960acab3c9f03cfcc682666699acfbe748d 100644 (file)
@@ -1839,6 +1839,57 @@ impl From<Extension> for TextRecord {
     }
 }
 
+#[derive(Clone, Debug)]
+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,
+        })
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct VariableSetRecord {
+    pub offsets: Range<u64>,
+    pub sets: Vec<VariableSet>
+}
+
+impl VariableSetRecord {
+    fn decode<'a>(source: &TextRecord, decoder: &Decoder) -> VariableSetRecord {
+        let mut sets = Vec::new();
+        let input = decoder.decode(&source.text);
+        for line in input.lines() {
+            if let Some(set) = VariableSet::parse(line).warn_on_error(&decoder.warn) {
+                sets.push(set)
+            }
+        }
+        VariableSetRecord { offsets: source.offsets.clone(), sets }
+    }
+}
+
+trait WarnOnError<T> {
+    fn warn_on_error<F: Fn(Error)>(self, warn: &F) -> Option<T>;
+}
+impl<T> WarnOnError<T> for Result<T, Error> {
+    fn warn_on_error<F: Fn(Error)>(self, warn: &F) -> Option<T> {
+        match self {
+            Ok(result) => Some(result),
+            Err(error) => {
+                warn(error);
+                None
+            }
+        }
+    }
+}
+
 #[derive(Clone, Debug)]
 pub struct Extension {
     pub offsets: Range<u64>,