use crate::application::engine::{ExecutionContext, ModuleHandle};
use crate::domain::resource::{Ensure, Resource};
use rhai::{Dynamic, Map};
use tracing::warn;
pub fn lock_or_warn<'a, T>(
mutex: &'a std::sync::Mutex<T>,
label: &str,
) -> Option<std::sync::MutexGuard<'a, T>> {
mutex
.lock()
.map_err(|e| {
warn!("Failed to lock {}: {}", label, e);
})
.ok()
}
pub struct DslUtils;
impl DslUtils {
pub fn extract_ensure(params: &Map) -> Ensure {
params
.get("ensure")
.and_then(|v| {
v.clone()
.try_cast::<String>()
.map(|s| match s.as_str() {
"absent" => Ensure::Absent,
_ => Ensure::Present,
})
.or_else(|| v.clone().try_cast::<Ensure>())
})
.unwrap_or(Ensure::Present)
}
pub fn extract_dependencies(
params: &Map,
ctx: &ExecutionContext,
source: Option<&str>,
) -> Vec<String> {
let mut dependencies = Vec::new();
if let Some(src) = source {
let s_map = ctx
.source_map
.lock()
.expect("Failed to lock source map");
if let Some(marker_id) = s_map.get(src) {
dependencies.push(marker_id.clone());
} else if let Some(stack_guard) = lock_or_warn(&ctx.module_stack, "module_stack")
&& let Some((inc_type, curr_mod)) = stack_guard.last()
{
dependencies.push(format!("{:?}Start[{}]", inc_type, curr_mod));
}
} else if let Some(stack_guard) = lock_or_warn(&ctx.module_stack, "module_stack") {
if let Some((inc_type, curr_mod)) = stack_guard.last() {
dependencies.push(format!("{:?}Start[{}]", inc_type, curr_mod));
}
}
if let Some(req) = params.get("require") {
Self::push_dependency(&mut dependencies, req.clone());
}
dependencies
}
pub fn push_dependency(dependencies: &mut Vec<String>, req: Dynamic) {
if let Some(m_h) = req.clone().try_cast::<ModuleHandle>() {
dependencies.push(m_h.end_id);
} else if let Some(dep_res) = req.clone().try_cast::<Resource>() {
dependencies.push(dep_res.id().to_string());
} else if let Some(dep_id) = req.clone().try_cast::<String>() {
dependencies.push(dep_id);
} else if let Some(m) = req.clone().try_cast::<rhai::Shared<rhai::Module>>() {
if let Some(m_h) = m
.get_var("module_handle")
.and_then(|v| v.try_cast::<ModuleHandle>())
{
dependencies.push(m_h.end_id);
}
} else if let Some(arr) = req.try_cast::<rhai::Array>() {
for item in arr {
Self::push_dependency(dependencies, item);
}
}
}
pub fn extract_string(params: &Map, key: &str) -> Option<String> {
params.get(key).and_then(|v| v.clone().try_cast::<String>())
}
pub fn extract_bool(params: &Map, key: &str, default: bool) -> bool {
params
.get(key)
.and_then(|v| v.clone().try_cast::<bool>())
.unwrap_or(default)
}
}