use std::path::Path;
use super::route::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).unwrap_or_else(|why| why))];
for held in entries::read_dir(&entries::dir(data_root)) {
let label = label(&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::Chunk> {
let flat = own(data_root);
let mut held = vec![chunk(
crate::ui::Channel {
name: OWN.to_owned(),
named_there: None,
dials: flat.clone().ok(),
},
flat.err(),
)];
held.extend(
entries::read_dir(&entries::dir(data_root))
.into_iter()
.map(|entry| {
chunk(
crate::ui::Channel {
name: entry.leaf,
named_there: Some(entry.workspace),
dials: entry
.channel
.as_ref()
.ok()
.map(|material| material.address.clone()),
},
entry.channel.err(),
)
}),
);
held
}
fn chunk(channel: crate::ui::Channel, unheld: Option<String>) -> crate::ui::Chunk {
crate::ui::Chunk {
channel,
held: unheld.map_or(crate::ui::Held::Unheard, crate::ui::Held::Unheld),
..crate::ui::Chunk::default()
}
}
pub(super) fn label(leaf: &str, workspace: &str) -> String {
if leaf == workspace {
leaf.to_owned()
} else {
format!("{leaf} (named {workspace:?} on its host)")
}
}
pub(super) fn names(data_root: &Path) -> String {
std::iter::once(OWN.to_owned())
.chain(
entries::read_dir(&entries::dir(data_root))
.into_iter()
.map(|held| format!("{:?}", held.leaf)),
)
.collect::<Vec<String>>()
.join(", ")
}
pub(super) fn rename(data_root: &Path, name: &str) -> String {
format!(
"if {name:?}'s material is already here under another directory name, \
rename that directory (`mv` it under {}) rather than minting a second \
leaf",
entries::dir(data_root).display()
)
}
fn own(data_root: &Path) -> Result<String, String> {
let dir = entries::flat(data_root);
match material::read_dir(&dir) {
Ok(Some(held)) => Ok(held.address),
Ok(None) => Err(format!(
"nothing provisioned at {}: {}",
dir.display(),
material::REMEDY
)),
Err(refusal) => Err(refusal),
}
}
fn row(label: &str, state: &str) -> String {
format!("{label}\n {state}")
}