use super::loaded::Entry;
use crate::registry::roster::ClientRow;
pub fn list(workspace: &str, observed: &str, rows: &[ClientRow]) -> String {
let head = format!("clients registered in workspace {workspace:?}, observed {observed}");
if rows.is_empty() {
return lines(&[head, String::new(), "(none is registered here)".to_owned()]);
}
let mut out = vec![head, String::new()];
out.extend(rows.iter().map(|row| {
format!(
" {} — {}, advertising {}",
row.client,
presence(row.present),
plural(row.tools.len(), "tool")
)
}));
out.push(String::new());
out.push("op=get with client=<name> for one client's advertised tools.".to_owned());
lines(&out)
}
pub fn get(workspace: &str, observed: &str, row: &ClientRow) -> String {
let mut out = vec![
format!(
"client {:?} of workspace {workspace:?}, observed {observed}",
row.client
),
format!(" {}", presence(row.present)),
String::new(),
];
if row.tools.is_empty() {
out.push("It advertises no tools.".to_owned());
return lines(&out);
}
out.push(format!(
"It advertises {}:",
plural(row.tools.len(), "tool")
));
for tool in &row.tools {
let entry = Entry {
client: row.client.clone(),
tool: tool.clone(),
};
out.push(format!(" {} — {}", tool.name, tool.description));
out.push(format!(" loads as: {}", entry.presented()));
}
out.push(String::new());
out.push(format!(
"op=load with client={:?} and tools=[…] makes them callable, \
by the names above, from the next step on.",
row.client
));
lines(&out)
}
pub fn load(observed: &str, added: &[Entry], total: usize) -> String {
let mut out = vec![format!("loaded, observed {observed}"), String::new()];
out.extend(
added
.iter()
.map(|entry| format!(" {} — {}", entry.presented(), entry.tool.description)),
);
out.push(String::new());
out.push(format!(
"Callable from the next step on. This conversation now holds {}. \
op=unload drops them again when you are done with that machine; \
a fresh conversation starts with none.",
plural(total, "loaded tool")
));
lines(&out)
}
pub fn unload(observed: &str, gone: &[Entry], total: usize) -> String {
let mut out = vec![format!("unloaded, observed {observed}"), String::new()];
out.extend(gone.iter().map(|entry| format!(" {}", entry.presented())));
out.push(String::new());
out.push(format!(
"No longer declared from the next step on. This conversation now holds {}. \
op=load makes any of them callable again.",
plural(total, "loaded tool")
));
lines(&out)
}
fn lines(rows: &[String]) -> String {
format!("{}\n", rows.join("\n"))
}
fn presence(present: bool) -> &'static str {
if present {
"connected right now"
} else {
"not connected right now"
}
}
fn plural(n: usize, noun: &str) -> String {
if n == 1 {
format!("{n} {noun}")
} else {
format!("{n} {noun}s")
}
}