use std::ops::ControlFlow;
use futures::SinkExt;
use tokio::sync::Mutex;
use tokio_tungstenite::tungstenite::Message;
use nodedb_types::sync::wire::{SyncFrame, SyncMessageType};
pub(super) async fn send_binary<S>(sink: &Mutex<S>, frame: SyncFrame) -> Result<(), S::Error>
where
S: SinkExt<Message> + Unpin,
{
let mut guard = sink.lock().await;
guard.send(Message::Binary(frame.to_bytes().into())).await
}
pub(super) async fn encode_and_send<S, T>(
sink: &Mutex<S>,
msg_type: SyncMessageType,
body: &T,
label: &'static str,
) -> ControlFlow<()>
where
S: SinkExt<Message> + Unpin,
S::Error: std::fmt::Display,
T: zerompk::ToMessagePack,
{
let Some(frame) = SyncFrame::try_encode(msg_type, body) else {
tracing::error!(label, "failed to encode {label} frame; skipping");
return ControlFlow::Continue(());
};
match send_binary(sink, frame).await {
Ok(()) => ControlFlow::Continue(()),
Err(e) => {
tracing::warn!(label, error = %e, "{label} send failed");
ControlFlow::Break(())
}
}
}