]> git.proxmox.com Git - proxmox-backup.git/commitdiff
section_config: improve parser
authorDietmar Maurer <dietmar@proxmox.com>
Mon, 26 Nov 2018 17:01:24 +0000 (18:01 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Mon, 26 Nov 2018 17:01:24 +0000 (18:01 +0100)
src/section_config.rs

index 910e20b5373081b6092cab5046a1a45a1ba578fd..980554e7e1518011c11af5ca88bdb9be87b40ad2 100644 (file)
@@ -1,3 +1,5 @@
+use failure::*;
+
 use std::fs::File;
 use std::io::Read;
 use std::collections::HashMap;
@@ -11,7 +13,12 @@ pub struct SectionConfigPlugin {
 pub struct SectionConfig {
     plugins: HashMap<String, SectionConfigPlugin>,
 
-    parse_section_header: fn(String) -> Value,
+    parse_section_header: fn(&str) ->  Option<(String, String)>,
+}
+
+enum ParseState {
+    BeforeHeader,
+    InsideSection,
 }
 
 impl SectionConfig {
@@ -23,18 +30,82 @@ impl SectionConfig {
         }
     }
 
-    pub fn parse(&self, filename: &str, raw: &str) {
+    pub fn parse(&self, filename: &str, raw: &str) -> Result<(), Error> {
+
+        let mut line_no = 0;
+
+       //let error_prefix = format!("file '{}' line {}", filename, line_no);
+       const ERROR_FORMAT: &str = "file '{}' line {} - {}";
+
+        let mut state = ParseState::BeforeHeader;
 
         for line in raw.lines() {
-            println!("LINE:{}", line);
+            line_no += 1;
+
+            if line.trim().is_empty() { continue; }
+
+            match state {
+
+                ParseState::BeforeHeader => {
+
+                    if line.trim().is_empty() { continue; }
+
+                    if let Some((section_type, section_id)) = (self.parse_section_header)(line) {
+                        println!("OKLINE: type: {} ID: {}", section_type, section_id);
+                        state = ParseState::InsideSection;
+                    } else {
+                        println!("file '{}' line {} - {}", filename, line_no, "syntax error  - expected header");
+                    }
+                }
+                ParseState::InsideSection => {
+
+                    if line.trim().is_empty() {
+                        // finish section
+                        state = ParseState::BeforeHeader;
+                        continue;
+                    }
+                    println!("CONTENT: {}", line);
+                }
+            }
+        }
+
+        if let ParseState::InsideSection = state {
+            // finish section
         }
+
+        Ok(())
     }
 
-    fn default_parse_section_header(line: String) -> Value {
+    pub fn default_parse_section_header(line: &str) -> Option<(String, String)> {
+
+        if line.len() == 0 { return None; };
+
+        let first_char = line.chars().next().unwrap();
+
+        if !first_char.is_alphabetic() { return None }
+
+        let mut head_iter = line.splitn(2, ':');
+
+        let section_type = match head_iter.next() {
+            Some(v) => v,
+            None => return None,
+        };
 
-        let config = json!({});
+        let section_type = section_type.trim();
 
-        config
+        if section_type.len() == 0 { return None; }
+
+        // fixme: verify format
+
+        let section_id = match head_iter.next() {
+            Some(v) => v,
+            None => return None,
+        };
+
+        let section_id = section_id.trim();
+
+
+        Some((section_type.into(), section_id.into()))
     }
 
 
@@ -55,6 +126,7 @@ fn test_section_config1() {
 
 
     let raw = r"
+
 lvmthin: local-lvm
         thinpool data
         vgname pve5