use crate::registry::tools::{self, Tool};
use super::Deps;
use crate::boundary::reply::Reply;
pub(super) fn advertise(deps: &Deps, tools: &[Tool]) -> Result<Reply, String> {
let client = &deps.caller.client;
if client.is_local() {
return Err(
"advertise: this intake carries no client identity — a tool set is presented \
by a connection, and the certificate is what says whose set it is"
.to_owned(),
);
}
tools::validate(tools)?;
superseding(deps, tools)?;
tools::store(&deps.state_root, client, tools).map_err(|e| e.to_string())?;
Ok(Reply::Advertised)
}
fn superseding(deps: &Deps, tools: &[Tool]) -> Result<(), String> {
let client = &deps.caller.client;
if !deps.caller.mailbox.serving(&client.name())
|| tools::read(&deps.state_root, client) == tools
{
return Ok(());
}
Err(format!(
"advertise: {:?} is holding this engine's follow-class read and this is not the \
set in force — a second connection may not replace a serving machine's tools, \
because the machine that is serving would never learn it was disarmed. \
Re-present the set in force, or stop the connection that is serving",
client.name()
))
}
#[cfg(test)]
mod tests;