pub vroutes: Vec<CidrString>,
}
-#[derive(Debug,Clone)]
+#[derive(Debug,Clone,Hash,Eq,PartialEq)]
pub enum SectionName {
Link { server: ServerName, client: ClientName },
Client(ClientName),
Server(ServerName), // includes SERVER, which is slightly special
+ ServerLimit(ServerName),
+ GlobalLimit,
Common,
Default,
}
pub use SectionName as SN;
-type SectionMap = HashMap<SectionName, Option<String>>;
+#[derive(Debug,Clone)]
+struct RawVal { val: Option<String>, loc: Arc<PathBuf> }
+type SectionMap = HashMap<String, RawVal>;
pub struct Config {
opts: Opts,
#[derive(Default,Debug)]
struct Aggregate {
- sections: HashMap<String, SectionMap>,
+ sections: HashMap<SectionName, SectionMap>,
}
type OkAnyway<'f,A> = &'f dyn Fn(ErrorKind) -> Option<A>;
match s {
"COMMON" => return SN::Common,
"DEFAULT" => return SN::Default,
+ "LIMIT" => return SN::GlobalLimit,
_ => { }
};
if let Ok(n@ ServerName(_)) = s.parse() { return SN::Server(n) }
if let Ok(n@ ClientName(_)) = s.parse() { return SN::Client(n) }
let (server, client) = s.split_ascii_whitespace().collect_tuple()
.ok_or_else(|| anyhow!(
- "bad section name \
- (must be COMMON, DEFAULT, <server>, <client>, or <server> <client>"
+ "bad section name {:?} \
+ (must be COMMON, DEFAULT, <server>, <client>, or <server> <client>",
+ s
))?;
let server = server.parse().context("server name in link section name")?;
+ if client == "LIMIT" { return SN::ServerLimit(server) }
let client = client.parse().context("client name in link section name")?;
SN::Link { server, client }
}
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 mut map = mem::take(ini.get_mut_map());
+ let map = mem::take(ini.get_mut_map());
if map.get(OUTSIDE_SECTION).is_some() {
throw!(anyhow!("INI file contains settings outside a section"));
}
- // xxx parse section names here
- // xxx save Arc<PathBuf> where we found each item
+ let loc = Arc::new(path.to_owned());
- for (sn, vars) in map.drain() {
+ for (sn, vars) in map {
let sn = sn.parse().dcontext(&sn)?;
- self.sections.entry(sn)
+ self.sections.entry(sn)
.or_default()
- .extend(vars);
+ .extend(
+ vars.into_iter()
+ .map(|(k,val)| {
+ (k.replace('-',"_"),
+ RawVal { val, loc: loc.clone() })
+ })
+ );
}
None
}
agg.read_extra(extra).context("extra config")?;
}
- eprintln!("GOT {:?}", agg);
+ eprintln!("GOT {:#?}", agg);
Ok::<_,AE>(())
})().context("read configuration")?;