use serde_json::{json, Value};
pub fn enumerate_all_overlays() -> Vec<(String, Value)> {
let mut out: Vec<(String, Value)> = Vec::new();
crate::exec::with_executor(|exec| {
if !exec.aliases.is_empty() {
out.push(("alias".into(), map_to_json(&exec.aliases)));
}
if !exec.global_aliases.is_empty() {
out.push(("galias".into(), map_to_json(&exec.global_aliases)));
}
if !exec.suffix_aliases.is_empty() {
out.push(("salias".into(), map_to_json(&exec.suffix_aliases)));
}
if !exec.options.is_empty() {
let map: serde_json::Map<String, Value> = exec
.options
.iter()
.map(|(k, v)| (k.clone(), Value::String(if *v { "on" } else { "off" }.into())))
.collect();
out.push(("setopt".into(), Value::Object(map)));
}
if !exec.variables.is_empty() || !exec.arrays.is_empty() || !exec.assoc_arrays.is_empty() {
let mut params = serde_json::Map::new();
for (k, v) in &exec.variables {
params.insert(k.clone(), Value::String(v.clone()));
}
for (k, v) in &exec.arrays {
params.insert(
k.clone(),
Value::Array(v.iter().map(|s| Value::String(s.clone())).collect()),
);
}
for (k, v) in &exec.assoc_arrays {
let inner: serde_json::Map<String, Value> = v
.iter()
.map(|(ik, iv)| (ik.clone(), Value::String(iv.clone())))
.collect();
params.insert(k.clone(), Value::Object(inner));
}
out.push(("params".into(), Value::Object(params)));
}
if !exec.fpath.is_empty() {
out.push((
"fpath".into(),
Value::Array(
exec.fpath
.iter()
.map(|p| Value::String(p.display().to_string()))
.collect(),
),
));
}
if !exec.named_dirs.is_empty() {
let map: serde_json::Map<String, Value> = exec
.named_dirs
.iter()
.map(|(k, v)| (k.clone(), Value::String(v.display().to_string())))
.collect();
out.push(("named_dir".into(), Value::Object(map)));
}
if !exec.completions.is_empty() {
let map: serde_json::Map<String, Value> = exec
.completions
.iter()
.map(|(k, v)| (k.clone(), json!(format!("{:?}", v))))
.collect();
out.push(("compdef".into(), Value::Object(map)));
}
if !exec.zstyles.is_empty() {
let arr: Vec<Value> = exec
.zstyles
.iter()
.map(|z| json!(format!("{:?}", z)))
.collect();
out.push(("zstyle".into(), Value::Array(arr)));
}
});
let mut env_map = serde_json::Map::new();
for (k, v) in std::env::vars() {
env_map.insert(k, Value::String(v));
}
if !env_map.is_empty() {
out.push(("env".into(), Value::Object(env_map)));
}
if let Ok(p) = std::env::var("PATH") {
let parts: Vec<Value> = p
.split(':')
.filter(|s| !s.is_empty())
.map(|s| Value::String(s.into()))
.collect();
if !parts.is_empty() {
out.push(("path".into(), Value::Array(parts)));
}
}
if let Ok(p) = std::env::var("MANPATH") {
let parts: Vec<Value> = p
.split(':')
.filter(|s| !s.is_empty())
.map(|s| Value::String(s.into()))
.collect();
if !parts.is_empty() {
out.push(("manpath".into(), Value::Array(parts)));
}
}
out
}
fn map_to_json(m: &std::collections::HashMap<String, String>) -> Value {
let map: serde_json::Map<String, Value> = m
.iter()
.map(|(k, v)| (k.clone(), Value::String(v.clone())))
.collect();
Value::Object(map)
}