use std::path::Path;
use serde_json::Value;
use super::{dial, fan, said};
use crate::channel::{Channel, Reach};
use crate::cli::{ON, Verdict};
use crate::envelope;
use crate::render::Form;
pub fn aimed(data_root: &Path, on: Option<&str>, envelope: &Value, form: Form) -> Verdict {
let channel = on.map_or_else(|| sole(data_root, envelope), |name| dial(data_root, name));
match channel
.map_err(Reach::Unsent)
.and_then(|open| open.ask(envelope))
{
Ok(stream) => Verdict::answered(said(&stream, form), envelope::succeeded(&stream)),
Err(reach) => Verdict::failed(reach.said()),
}
}
fn sole(data_root: &Path, envelope: &Value) -> Result<Channel, String> {
match <[_; 1]>::try_from(fan::held(data_root)) {
Ok([(_, channel)]) => channel,
Err(held) => Err(format!(
"this box holds {} channels and `{}` writes one engine's world, so \
name the one with `{ON} <channel>`: {}",
held.len(),
envelope::op(envelope),
held.into_iter()
.map(|(name, _)| name)
.collect::<Vec<String>>()
.join(", ")
)),
}
}
#[cfg(test)]
mod tests;