use iridium_stomp::{ConnectOptions, Connection, Frame};
use std::time::Duration;
use super::args::Cli;
use super::exit_codes;
use super::plain::format_connection_error_pub;
pub async fn run(cli: &Cli, destination: &str, body: &str) -> Result<(), (String, u8)> {
if !destination.starts_with('/') {
return Err((
format!(
"Invalid destination '{}'. Must start with / (e.g., /topic/test, /queue/test)",
destination
),
exit_codes::PROTOCOL_ERROR,
));
}
let timeout = Duration::from_secs(cli.timeout);
let options = ConnectOptions::default().disconnect_timeout(timeout);
let conn = tokio::time::timeout(
timeout,
Connection::connect_with_options(
&cli.address,
&cli.login,
&cli.passcode,
&cli.heartbeat,
options,
),
)
.await
.map_err(|_| {
(
format!(
"Timed out after {}s connecting to {}",
cli.timeout, cli.address
),
exit_codes::NETWORK_ERROR,
)
})?
.map_err(|e| format_connection_error_pub(&e, &cli.address))?;
let frame = Frame::new("SEND")
.header("destination", destination)
.header("content-type", "text/plain")
.set_body(body.as_bytes().to_vec());
let sent = conn
.send_frame_confirmed(frame, timeout)
.await
.map_err(|e| format_connection_error_pub(&e, &cli.address));
let closed = conn.close().await;
sent?;
if let Err(e) = closed {
eprintln!("Warning: broker did not confirm the disconnect: {}", e);
}
println!("Sent to {}", destination);
Ok(())
}