use std::collections::BTreeMap;
use std::fs::File;
use std::io::{BufRead, BufReader, Result, Write};
use std::path::Path;
#[derive(Debug)]
pub struct LoadedEntry {
pub name: String,
pub oid: String,
pub sn: String,
pub description: String,
}
pub type LoadedMap = BTreeMap<String, Vec<LoadedEntry>>;
pub fn load_file<P: AsRef<Path>>(path: P) -> Result<LoadedMap> {
let mut map = BTreeMap::new();
let file = File::open(path)?;
for line in BufReader::new(file).lines() {
let line = line?;
if line.is_empty() || line.starts_with('#') {
continue;
}
let mut iter = line.splitn(5, '\t');
let feature = iter.next().expect("invalid oid_db format: missing feature").replace('-', "_");
let name = iter.next().expect("invalid oid_db format: missing name").to_string();
let oid = iter.next().expect("invalid oid_db format: missing OID").to_string();
let sn = iter.next().expect("invalid oid_db format: missing short name").to_string();
let description = iter.next().expect("invalid oid_db format: missing description").to_string();
let entry = LoadedEntry {
name,
oid,
sn,
description,
};
let v = map.entry(feature.to_string()).or_insert_with(Vec::new);
v.push(entry);
}
Ok(map)
}
pub fn generate_file<P: AsRef<Path>>(map: &LoadedMap, dest_path: P) -> Result<()> {
let mut out_file = File::create(&dest_path)?;
for feat_entries in map.values() {
for v in feat_entries {
if v.name != "\"\"" {
writeln!(out_file, "/// {}", v.oid)?;
writeln!(out_file, "pub const {}: Oid<'static> = oid!({});", v.name, v.oid)?;
}
}
}
writeln!(out_file)?;
writeln!(out_file, r#"#[cfg(feature = "registry")]"#)?;
writeln!(out_file, r#"#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]"#)?;
writeln!(out_file, "impl<'a> OidRegistry<'a> {{")?;
for (k, v) in map {
writeln!(out_file, r#" #[cfg(feature = "{}")]"#, k)?;
writeln!(out_file, r#" #[cfg_attr(docsrs, doc(cfg(feature = "{}")))]"#, k)?;
writeln!(
out_file,
r#" #[doc = "Load all known OIDs for feature `{}` in the registry."]"#,
k
)?;
writeln!(out_file, " pub fn with_{}(mut self) -> Self {{", k)?;
for item in v {
writeln!(
out_file,
r#" self.insert(oid!({}), OidEntry::new("{}", "{}"));"#,
item.oid, item.sn, item.description
)?;
}
writeln!(out_file, " self")?;
writeln!(out_file, " }}")?;
writeln!(out_file)?;
}
writeln!(out_file, "}}")?;
Ok(())
}