use std::path::Path;
use super::flat;
use crate::channel::{Channel, entries, material};
use crate::cli::Verdict;
pub const OWN: &str = "(this box's own engine)";
pub fn listing(data_root: &Path) -> Verdict {
let mut rows = vec![row(OWN, &own(data_root))];
for held in entries::read_dir(&entries::dir(data_root)) {
let label = if held.workspace == held.leaf {
held.leaf.clone()
} else {
format!("{} (named {:?} on its host)", held.leaf, held.workspace)
};
let state = held
.channel
.map_or_else(|state| state, |material| material.address);
rows.push(row(&label, &state));
}
Verdict::ok(rows.join("\n"))
}
pub fn dial(data_root: &Path, name: &str) -> Result<Channel, String> {
if name == OWN {
return flat(data_root);
}
entries::read_dir(&entries::dir(data_root))
.into_iter()
.find(|held| held.leaf == name)
.ok_or_else(|| format!("this box holds no channel named {name:?}"))?
.open()
}
pub fn channels(data_root: &Path) -> Vec<crate::ui::Channel> {
let mut held = vec![crate::ui::Channel {
name: OWN.to_owned(),
named_there: None,
}];
held.extend(
entries::read_dir(&entries::dir(data_root))
.into_iter()
.map(|entry| crate::ui::Channel {
name: entry.leaf,
named_there: Some(entry.workspace),
}),
);
held
}
fn own(data_root: &Path) -> String {
let dir = entries::flat(data_root);
match material::read_dir(&dir) {
Ok(Some(held)) => held.address,
Ok(None) => format!("nothing provisioned at {}", dir.display()),
Err(refusal) => refusal,
}
}
fn row(label: &str, state: &str) -> String {
format!("{label}\n {state}")
}