use std::path::Path;
use serde_json::Value;
use super::{OWN, holds, lines};
use crate::channel::entries;
use crate::cli::Verdict;
use crate::envelope;
pub fn fanned(data_root: &Path, envelope: &Value) -> Verdict {
let asked: Vec<(String, Result<Vec<Value>, String>)> =
std::iter::once((OWN.to_owned(), super::route::flat(data_root)))
.chain(
entries::read_dir(&entries::dir(data_root))
.into_iter()
.map(|held| (holds::label(&held.leaf, &held.workspace), held.open())),
)
.map(|(name, channel)| {
let said = channel
.map_err(crate::channel::Reach::Unsent)
.and_then(|open| open.ask(envelope))
.map_err(|reach| reach.said());
(name, said)
})
.collect();
let answered = asked.iter().any(|(_, said)| {
said.as_ref()
.is_ok_and(|stream| envelope::succeeded(stream))
});
let text = asked
.iter()
.map(|(name, said)| section(name, said))
.collect::<Vec<String>>()
.join("\n");
Verdict::answered(text, answered)
}
fn section(name: &str, said: &Result<Vec<Value>, String>) -> String {
let body = match said {
Ok(stream) => lines(stream),
Err(refusal) => refusal.clone(),
};
std::iter::once(name.to_owned())
.chain(body.lines().map(|line| format!(" {line}")))
.collect::<Vec<String>>()
.join("\n")
}
#[cfg(test)]
mod tests;