use regex::{Captures, Regex};
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, HashSet},
fs::File,
io::BufReader,
path::{Path, PathBuf},
};
use crate::connector::{OutputMapFile, PhysicalAddress};
#[derive(Debug, Serialize, Deserialize, Hash, Clone, Eq, PartialEq)]
pub struct ReadOutput {
pub addr: PathBuf,
pub key: String,
}
impl ReadOutput {
pub fn to_string(&self) -> String {
format!("out://{}[{}]", self.addr.to_string_lossy(), self.key)
}
}
pub fn get_read_outputs(config: &str) -> Vec<ReadOutput> {
let re = Regex::new(r#"out://([^\[]+)\[([^\]]+)\]"#).unwrap();
let mut outputs = Vec::new();
for cap in re.captures_iter(config) {
let filename = cap.get(1).map(|m| m.as_str()).unwrap_or("");
let key = cap.get(2).map(|m| m.as_str()).unwrap_or("");
outputs.push(ReadOutput {
addr: PathBuf::from(filename),
key: key.to_string(),
});
}
outputs
}
pub struct TemplateResourceResult {
pub body: String,
pub missing: HashSet<ReadOutput>,
}
pub fn template_config(prefix: &Path, config: &str) -> anyhow::Result<TemplateResourceResult> {
let re = Regex::new(r#"out://(?<addr>[^\[]+)\[(?<key>[^\]]+)\]"#)?;
let mut missing = HashSet::<ReadOutput>::new();
let output = re.replace_all(config, |caps: &Captures| {
let addr = &caps["addr"];
let key = &caps["key"];
let phy_addr = PathBuf::from(addr);
let addr = PathBuf::from(addr);
let prefix = prefix.to_path_buf();
match OutputMapFile::get(&prefix, &phy_addr, key) {
Ok(Some(val)) => val,
_ => {
let val = caps.get(0).unwrap().as_str().to_string();
missing.insert(ReadOutput {
addr,
key: key.to_string(),
});
val
}
}
});
Ok(TemplateResourceResult {
body: output.into_owned(),
missing,
})
}