use std::collections::HashMap;
use epics_base_rs::server::database::PvDatabase;
use epics_base_rs::server::iocsh::macro_defn_pairs;
pub fn parse_macros(input: &str) -> HashMap<String, String> {
macro_defn_pairs(input)
.into_iter()
.filter_map(|(name, value)| value.map(|v| (name, v)))
.collect()
}
fn require_macro(
macros: &HashMap<String, String>,
key: &str,
program: &str,
) -> Result<String, String> {
macros
.get(key)
.cloned()
.ok_or_else(|| format!("{program}: required macro '{key}' not specified"))
}
pub fn seq_start(
program: &str,
macro_str: &str,
bridge: &epics_base_rs::runtime::task::BlockingBridge,
db: &PvDatabase,
) -> Result<(), String> {
let macros = parse_macros(macro_str);
match program {
"delayDo" => {
let config = crate::snl::delay_do::DelayDoConfig::new(
&require_macro(¯os, "P", program)?,
&require_macro(¯os, "R", program)?,
);
let db = db.clone();
bridge.spawn(async move {
if let Err(e) = crate::snl::delay_do::run(config, db).await {
eprintln!("delayDo error: {e}");
}
});
}
"femto" => {
let config = crate::snl::femto::FemtoConfig::new(
&require_macro(¯os, "P", program)?,
&require_macro(¯os, "H", program)?,
&require_macro(¯os, "F", program)?,
&require_macro(¯os, "G1", program)?,
&require_macro(¯os, "G2", program)?,
&require_macro(¯os, "G3", program)?,
&require_macro(¯os, "NO", program)?,
);
let db = db.clone();
bridge.spawn(async move {
if let Err(e) = crate::snl::femto::run(config, db).await {
eprintln!("femto error: {e}");
}
});
}
other => return Err(format!("seq_start: unknown std program '{other}'")),
}
Ok(())
}