chiark / gitweb /
ini: use instead of configparser
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 20:29:02 +0000 (21:29 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 7 Aug 2021 20:29:02 +0000 (21:29 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Cargo.lock
Cargo.toml
src/config.rs
src/prelude.rs

index 3ffac8c9e2d204da23b1939ba49ca79f1fbc5980..792e1e75f6bb476765cb21f8279ce1a3df4edae9 100644 (file)
@@ -127,12 +127,6 @@ dependencies = [
  "vec_map",
 ]
 
-[[package]]
-name = "configparser"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7201ee416d124d589a820111ba755930df8b75855321a9a1b87312a0597ec8f"
-
 [[package]]
 name = "core-foundation"
 version = "0.9.1"
@@ -420,7 +414,6 @@ dependencies = [
  "backtrace",
  "base64",
  "cervine",
- "configparser",
  "env_logger",
  "extend",
  "eyre",
index 68e1d474523febbb8b17fc7e2b6aaeca231af549..f382f24139372ece467244093fdd86ac5392225a 100644 (file)
@@ -29,7 +29,6 @@ hippotat-macros = { path = "macros" }
 # (or currently available):
 backtrace = "0.3"
 base64 = "0.13"
-configparser = "2"
 env_logger = "0.9"
 futures = "0.3"
 hyper = { version = "0.14", features = ["full"] }
index c373549af83e7b51a279ef040f4285807f127816..c65dbea2983247edc71274557ee49f35ece34034 100644 (file)
@@ -4,8 +4,6 @@
 
 use crate::prelude::*;
 
-use configparser::ini::Ini; // xxx ignores empty sections, fix or replace
-
 #[derive(hippotat_macros::ResolveConfig)]
 #[derive(Debug,Clone)]
 pub struct InstanceConfig {
@@ -132,15 +130,11 @@ pub enum SectionName {
 }
 pub use SectionName as SN;
 
-#[derive(Debug,Clone)]
-struct RawVal { raw: Option<String>, loc: Arc<PathBuf> }
-type SectionMap = HashMap<String, RawVal>;
-
 #[derive(Debug)]
 struct RawValRef<'v,'l,'s> {
-  raw: Option<&'v str>,
+  raw: Option<&'v str>, // todo: not Option any more
   key: &'static str,
-  loc: &'l Path,
+  loc: &'l ini::Loc,
   section: &'s SectionName,
 }
 
@@ -165,7 +159,7 @@ static SPECIAL_SERVER_SECTION: &str = "SERVER";
 struct Aggregate {
   end: LinkEnd,
   keys_allowed: HashMap<&'static str, SectionKindList>,
-  sections: HashMap<SectionName, SectionMap>,
+  sections: HashMap<SectionName, ini::Section>,
 }
 
 type OkAnyway<'f,A> = &'f dyn Fn(ErrorKind) -> Option<A>;
@@ -248,18 +242,16 @@ impl Aggregate {
 
   #[throws(AE)] // AE does not include path
   fn read_string(&mut self, s: String, path_for_loc: &Path) {
-    let mut ini = Ini::new_cs();
-    ini.set_default_section(OUTSIDE_SECTION);
-    ini.read(s).map_err(|e| anyhow!("{}", e)).context("parse as INI")?;
-    let map = mem::take(ini.get_mut_map());
+    let mut map: ini::Parsed = default();
+    ini::read(&mut map, &mut s.as_bytes(), path_for_loc)
+      .context("parse as INI")?;
     if map.get(OUTSIDE_SECTION).is_some() {
       throw!(anyhow!("INI file contains settings outside a section"));
     }
 
-    let loc = Arc::new(path_for_loc.to_owned());
-
-    for (sn, vars) in map {
+    for (sn, section) in map {
       let sn = sn.parse().dcontext(&sn)?;
+      let vars = &section.values;
 
       for key in vars.keys() {
         let skl = if key == "server" {
@@ -275,30 +267,34 @@ impl Aggregate {
         }
       }
 
-      let ent = self.sections.entry(sn).or_default();
-      for (key, raw) in vars {
-        let raw = match raw {
-          Some(raw) if raw.starts_with('\'') || raw.starts_with('"') => Some(
-            (||{
-              if raw.contains('\\') {
-                throw!(
-                  anyhow!("quoted value contains backslash, not supported")
-                );
-              }
-              let unq = raw[1..].strip_suffix(&raw[0..1])
-                .ok_or_else(
-                  || anyhow!("mismatched quotes around quoted value")
-                )?
-                .to_owned();
-              Ok::<_,AE>(unq)
-            })()
-              .with_context(|| format!("key {:?}", key))
-              .dcontext(path_for_loc)?
-          ),
-          x => x,
+      let ent = self.sections.entry(sn)
+        .or_insert_with(|| ini::Section {
+          loc: section.loc.clone(),
+          values: default(),
+        });
+
+      for (key, ini::Val { val: raw, loc }) in vars {
+        let val = if raw.starts_with('\'') || raw.starts_with('"') {
+          (||{
+            if raw.contains('\\') {
+              throw!(
+                anyhow!("quoted value contains backslash, not supported")
+              );
+            }
+            let unq = raw[1..].strip_suffix(&raw[0..1])
+              .ok_or_else(
+                || anyhow!("mismatched quotes around quoted value")
+              )?
+              .to_owned();
+            Ok::<_,AE>(unq)
+          })()
+            .with_context(|| format!("key {:?}", key))
+            .dcontext(path_for_loc)?
+        } else {
+          raw.clone()
         };
         let key = key.replace('-',"_");
-        ent.insert(key, RawVal { raw, loc: loc.clone() });
+        ent.values.insert(key, ini::Val { val, loc: loc.clone() });
       }
     }
   }
@@ -418,7 +414,7 @@ impl Aggregate {
     };
 
     for (section, vars) in &self.sections {
-      let has_secret = || vars.contains_key("secret");
+      let has_secret = || vars.values.contains_key("secret");
       //dbg!(&section, has_secret());
 
       match section {
@@ -569,13 +565,13 @@ impl Aggregate {
   where S: Iterator<Item=&'s SectionName>
   {
     for section in sections {
-      if let Some(raw) = self.sections
+      if let Some(val) = self.sections
         .get(section)
-        .and_then(|vars: &SectionMap| vars.get(key))
+        .and_then(|s: &ini::Section| s.values.get(key))
       {
         return Some(RawValRef {
-          raw: raw.raw.as_deref(),
-          loc: &raw.loc,
+          raw: Some(&val.val),
+          loc: &val.loc,
           section, key,
         })
       }
index 355f588d450be1e202cd521c0486a116b11ef884..5e4261d0407c5e88f405f96006a88122b5f440de 100644 (file)
@@ -49,6 +49,7 @@ pub use eyre::WrapErr;
 pub use eyre::Error as AE;
 
 pub use crate::config::{self, InstanceConfig, u32Ext as _};
+pub use crate::ini;
 pub use crate::utils::*;
 pub use crate::queue::*;
 pub use crate::reporter::*;