chiark / gitweb /
ini: wip new module
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 19:51:32 +0000 (20:51 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 19:51:32 +0000 (20:51 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/ini.rs
src/prelude.rs

index a8c955864ce018f29ecfd5915249ed6c93e9ba7d..67817f525e1401673c1f7d0c2f85532b5f3624a2 100644 (file)
@@ -2,15 +2,21 @@
 // SPDX-License-Identifier: GPL-3.0-or-later
 // There is NO WARRANTY.
 
+use crate::prelude::*;
+
+use std::io::BufRead;
+
+#[derive(Debug,Clone)]
+#[derive(Hash,Eq,PartialEq,Ord,PartialOrd)]
 pub struct Loc {
   pub file: Arc<PathBuf>,
-  pub line: usize,
+  pub lno: usize,
   pub section: Option<Arc<String>>,
 }
 
 #[derive(Debug,Clone)]
-pub struct RawVal {
-  pub raw: String,
+pub struct Val {
+  pub val: String,
   pub loc: Loc,
 }
 
@@ -19,15 +25,15 @@ pub type Parsed = HashMap<Arc<String>, Section>;
 pub struct Section {
   /// Location of first encounter
   pub loc: Loc,
-  pub values: HashMap<String, RawVal>,
+  pub values: HashMap<String, Val>,
 }
 
 impl Display for Loc {
   #[throws(fmt::Error)]
   fn fmt(&self, f: &mut fmt::Formatter) {
-    write!(f, "{}:{}", &self.file, self.line)?;
+    write!(f, "{:?}:{}", &self.file, self.lno)?;
     if let Some(s) = &self.section {
-      let dbg = format!("{:?}", &m);
+      let dbg = format!("{:?}", &s);
       if let Some(mid) = (||{
         let mid = dbg.strip_prefix(r#"""#)?;
         let mid = mid.strip_suffix(r#"""#)?;
@@ -42,53 +48,56 @@ impl Display for Loc {
 }
 
 #[throws(AE)]
-pub fn read(parsed: &mut Parsed, file: &dyn BufRead, path_for_loc: &Path) {
-  let path = path_for_loc.to_owned().into();
+pub fn read(parsed: &mut Parsed, file: &mut dyn BufRead, path_for_loc: &Path) {
+  let path: Arc<PathBuf> = path_for_loc.to_owned().into();
   let section: Option<&mut Section> = None;
   for (lno, line) in file.lines().enumerate() {
     let line = line.context("read")?;
-    (||{
-      let line = line.trim();
+    let line = line.trim();
 
-      if line.is_empty() { continue }
-      if regex_is_match!(r#"^ [;#] "#x, line) { continue }
+    if line.is_empty() { continue }
+    if regex_is_match!(r#"^ [;#] "#x, line) { continue }
 
-      let mut loc = Loc {
-        line,
-        file: path.clone(),
-        section: section.as_ref().map(|s| s.section.clone()),
-      };
+    let mut loc = Loc {
+      lno,
+      file: path.clone(),
+      section: section.as_ref().map(|s| s.loc.section.unwrap().clone()),
+    };
+    (|| Ok::<(),AE>({
 
-      if let Some((_,section,)) =
+      if let Some((_,new,)) =
         regex_captures!(r#"^ \[ \s* (.+?) \s* \] $"#x, line)
       {
-        let sname = Some(section.to_owned().into());
-        section = Some(parsed.entry(sname.clone())
-          .get_or_insert_with(|| {
-            Section {
-              loc: Loc { section: sname, ..loc },
-              values: default(),
-            }
-          }));
-        continue;
-      }
+        let new: Arc<String> = new.to_owned().into();
+        section = Some(
+          parsed.entry(new.clone())
+            .or_insert_with(|| {
+              Section {
+                loc: Loc { section: Some(new), ..loc },
+                values: default(),
+              }
+            })
+        );
 
-      if let Some((_,k,v)) =
+      } else if let Some((_, key, val)) =
         regex_captures!(r#"^ ( [^\[] .*? ) \s* = \s* (.*) $"#, line)
       {
-        section.values.insert(k.into(), RawVal {
-          loc,
-          raw: v.into(),
-        });
-        continue;
-      }
+        let val = Val { loc, val: val.into() };
+
+        section
+          .as_mut()
+          .ok_or_else(|| anyhow!("value outside section"))?
+          .values
+          .insert(key.into(), val);
 
-      throw!(if line.starts_with("[") {
-        anyhow!(r#"syntax error (section missing final "]"?)"#)
       } else {
-        anyhow!(r#"syntax error (setting missing "="?)"#)
-      })
+        throw!(if line.starts_with("[") {
+          anyhow!(r#"syntax error (section missing final "]"?)"#)
+        } else {
+          anyhow!(r#"syntax error (setting missing "="?)"#)
+        })
+      }
 
-    })().with_context(|| loc().to_string())?
+    }))().with_context(|| loc.to_string())?
   }
 }
index 277513a18501ebf3b326f3298717ea4cc04d6709..355f588d450be1e202cd521c0486a116b11ef884 100644 (file)
@@ -32,7 +32,7 @@ pub use hyper::Uri;
 pub use hyper_tls::HttpsConnector;
 pub use ipnet::IpNet;
 pub use itertools::{iproduct, Itertools};
-pub use lazy_regex::{regex_is_match, regex_replace_all};
+pub use lazy_regex::{regex_captures, regex_is_match, regex_replace_all};
 pub use log::{trace, debug, info, warn, error};
 pub use structopt::StructOpt;
 pub use thiserror::Error;